#include <sys_config.h>
#include <basic_types.h>
#include <retcode.h>
#include <mediatypes.h>
#include <osal/osal.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/nim/nim_dev.h>
#include <hld/nim/nim.h>
#include <hld/dmx/dmx_dev.h>
#include <hld/dmx/dmx.h>
#include <hld/deca/deca_dev.h>
#include <hld/deca/deca.h>
#include <hld/snd/snd_dev.h>
#include <hld/snd/snd.h>
#include <hld/decv/vdec_driver.h>
#include <hld/dis/VPO.h>
#include <hld/cic/cic.h>
#include <api/libci/ci_plus.h>

#include <api/libpub/lib_pub.h>
#include <api/libpub/lib_hde.h>
#include <api/libpub/lib_frontend.h>
#include <api/libpub/lib_device_manage.h>

#include <bus/tsi/tsi.h>
#include<api/libsi/lib_epg.h>
#include <api/libsi/si_service_type.h>
#include <api/libsi/si_tdt.h>
#include <api/libsi/lib_nvod.h>
#include <api/libsi/sie_monitor.h>
#ifdef MULTI_CAS
#include <api/libcas/mcas.h>
#endif
#ifdef CC_USE_TSG_PLAYER
#include <api/libpvr/lib_pvr.h>
#endif

#if (defined(_MHEG5_V20_ENABLE_) )
#include <mh5_api/mh5_api.h>
#endif

#ifdef SUPPORT_CAS9
#include <api/libcas/cas9/cas9.h>
#endif

#ifdef SUPPORT_VMX_STD
#ifdef VMX_NEW_CC
#include "../../../../../prj/app/demo/combo/sabbat_dual/vmx_ap_s/vmx_cas.h"
#else
#include "../../../../../prj/app/demo/combo/sabbat_dual/vmx_ap_std/vmx_cas.h"
#endif
#endif

/*******************************************************
* macro define
********************************************************/
#define CC_PRINTF   PRINTF//libc_printf
//#define CHANNEL_CHANGE_VIDEO_FAST_SHOW


#if defined(SUPPORT_VMX_STD) || defined(SUPPORT_VMX)	// cover VMX_PATCH_CC
#if 0
#define VMX_API_PRINTF		libc_printf
#else
#define VMX_API_PRINTF(...)	do{}while(0)
#endif
#endif

#ifdef PUB_PORTING_PUB29
#define CC_STATE_STOP			0
#define CC_STATE_PLAY_TV		1
#define CC_STATE_PLAY_RADIO	2
#endif

/*******************************************************
* extern declare
********************************************************/
extern struct pub_module_config libpub_config;
#ifndef PUB_PORTING_PUB29
extern BOOL cc_aerial_signal_monitor(struct ft_frontend *ft);//(UINT32 sfreq, UINT16 bandwidth)
#endif
#if (defined(PUB_PORTING_PUB29)) && ((SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC)) )
extern BOOL cc_aerial_signal_monitor(UINT32 sfreq, UINT16 bandwidth);
#endif

/*******************************************************
* struct and variable
********************************************************/
extern UINT16 l_cc_sema_id;
#define ENTER_CC_API()  osal_semaphore_capture(l_cc_sema_id, TMO_FEVR)
#define LEAVE_CC_API()  osal_semaphore_release(l_cc_sema_id)

//ci device & service data
static struct ci_device_list ci_dev_list;
static struct ci_service_info ci_service;

#ifdef PUB_PORTING_PUB29
typedef INT32 (*cc_notify_callback)(UINT32 param);
cc_notify_callback post_play_callback = NULL;
static UINT32 l_cc_crnt_state = CC_STATE_STOP;
#if (SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC))
static struct cc_xpond_info play_xpond_info;
#endif
#endif

static BOOL pub_blk_scrn = FALSE;
static INT32 cc_cmd_cnt = 0;		//play channel cmd counter for CI

#ifdef MULTI_CAS
static BOOL mcas_xpond_stoped = FALSE;//a temp solution to make sure api_mcas_start_transponder()
										//is called pair with api_mcas_stop_transponder()
#endif
#ifdef VMX_PVR_SUPPORT
static UINT8 g_pre_nim_id = 0;
#endif
/********************************************************
*internal functions
/*******************************************************/

static void cb_vdec_first_show(UINT32 uParam1, UINT32 uParam2);
#ifdef CI_SERVICE_SHUNNING_DEBUG_PRINT
#define CI_SHUNNING_DEBUG libc_printf
#else
#define CI_SHUNNING_DEBUG(...) do{} while(0)
#endif

/* BEGIN: tsg ci patch code */
//#define CHCHG_TICK_PRINTF

#ifdef CHCHG_TICK_PRINTF
UINT32 cc_play_tick = 0;
UINT32 vdec_start_tick = 0;
#endif


#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
UINT32 ciplus_cc_begin_tick = 0;
UINT32 ciplus_cc_prev_tick = 0;
#endif

BOOL is_multiview_play = FALSE;
#ifdef CC_USE_TSG_PLAYER
static void cc_start_patch(UINT8 slot_mask)
{
#ifdef _DEBUG_PATCH
	libc_printf("patch -> start tsg - tick %d\n",osal_get_tick());
#endif
#ifdef CI_SUPPORT
	api_ci_mutex_lock();

    cc_tsg_task_start(ci_service.prog_id);
//	libc_printf("patch -> start tsg done - tick %d\n",osal_get_tick());

	//generally need some time to wait the TS be steady.
//	osal_task_sleep(20);
	api_ci_start_service(&ci_dev_list, &ci_service, slot_mask);

	api_ci_mutex_unlock();
#endif
}

static void cc_stop_patch()
{
#ifdef _DEBUG_PATCH
	libc_printf("patch -> stop tsg - tick %d\n",osal_get_tick());
#endif
#ifdef CI_SUPPORT
    if (cc_tsg_task_is_running())
    {
        cc_tsg_task_stop();
    }
#endif
//	libc_printf("patch -> stop tsg done - tick %d\n",osal_get_tick());
}
#endif
/* END: tsg ci patch code */


/* Set hdmi audio output when cc play */
/* Peter Feng, 2008.06.13 */
static void set_hdmi_audio_output(BOOL enable)
{
#ifdef SUPPORT_HDMI_CAT
	// call CAT driver to enable/disable audio
	CC_PRINTF("HDMI --- Play channel enable/disable audio is %d.\n", enable);
	HDMI_CAT6611_Enable_AudioOutput(enable);
#endif

#ifdef SUPPORT_HDMI_CAT6613
	// call CAT driver to enable/disable audio
	CC_PRINTF("HDMI --- Play channel enable/disable audio is %d.\n", enable);
	HDMITX_CAT6613_Enable_AudioOutput(enable);
#endif
}

/* Set Audio Channel Mode: Left, Right, Mono, or Stereo */
static void set_audio_channel(struct snd_device *snd_dev, UINT16 audio_ch)
{
    	enum SndDupChannel chan;

	switch(audio_ch)
	{
	case AUDIO_CH_L:
		chan = SND_DUP_L;
		break;
	case AUDIO_CH_R:
        	chan = SND_DUP_R;
        	break;
       case AUDIO_CH_MONO:
        	chan = SND_DUP_MONO;
        	break;
       case AUDIO_CH_STEREO:
       default:
        	chan = SND_DUP_NONE;
        	break;
	}
	snd_set_duplicate(snd_dev, chan);
}

// Temp Solution for DVB-C: Add Macro
#if (SYS_PROJECT_FE != PROJECT_FE_DVBC) || defined(CI_PLUS_SUPPORT)
/* Start SIE Monitor of one Prog */
static void cc_sim_start_monitor(struct cc_es_info *es, struct dmx_device *dmx)
{
	P_NODE node;
	UINT16 prog_pos = 0xffff;
	UINT32 sim_id =0xffffffff;
		
	if (es == NULL || dmx == NULL)
	{
		CC_PRINTF("cc_sim_start_monitor: input parameter null!\n");
		return;
	}

	// Get Program Index from DB
	prog_pos = get_prog_pos(es->prog_id);
	if (0xffff == prog_pos)
	{
		CC_PRINTF("cc_sim_start_monitor: get prog index failure!\n");
		return;
	}
	
	// Get Program Attribute from DB
	if(get_prog_at(prog_pos, &node) != SUCCESS)
	{
		CC_PRINTF("cc_sim_start_monitor: get prog attribute failure!\n");
		return;
	}

	// Start SIE Monitor
	sim_id = sim_start_monitor(dmx, MONITE_TB_PMT, node.pmt_pid, es->service_id);
	if( 0xffffffff == sim_id)
	{
		CC_PRINTF("cc_sim_start_monitor: start si monitor failure!\n");
    	}
	else
	{
		es->sim_id = sim_id;
	}
}

/* Stop SIE Monitor of one Prog */
static void cc_sim_stop_monitor(struct cc_es_info *es)
{
	// Stop SIE Monitor
	if (sim_stop_monitor(es->sim_id) != SUCCESS)
		CC_PRINTF("cc_sim_stop_monitor: stop si monitor failure\n");
}
#else
static void cc_sim_start_monitor(struct cc_es_info * es, struct dmx_device * dmx)
{

}
static void cc_sim_stop_monitor(struct cc_es_info * es)
{

}
#endif

BOOL get_is_multiview_play(void)
{
    return is_multiview_play;
}
void set_is_multiview_play(BOOL value)
{
    is_multiview_play = value;
}
BOOL enable_blk_screen = TRUE;
void enable_fill_blk_screen(BOOL b_eanble)
{
	enable_blk_screen = b_eanble;
}

#ifdef CHANCHG_VIDEOTYPE_SUPPORT
struct cc_backup_addr 
{
	UINT8  *top_y_base[2];
	UINT8  *top_c_base[2];
	UINT8  *maf_buf_base[2];
};

enum BACKUP_PIC_RES
{
	CMD_NOT_IMPLEMENT,
	NO_PICTURE_SHOWED,
	MALLOC_MEMORY_FAIL,
	MALLOC_MEMORY_OK,
	BACKUP_PICTURE_FAIL,
	BACKUP_PICTURE_OK,
};

static struct cc_backup_addr cc_backup_info;

void *cc_backup_malloc(unsigned int size)
{
	void *ptr = MALLOC(size);
	if (ptr)
		MEMSET(ptr, 0, size);
	return ptr;
}

void cc_backup_free()
{
	UINT32 i;

	for(i=0; i<2; i++)
	{
		if(cc_backup_info.top_y_base[i] != NULL)
			FREE(cc_backup_info.top_y_base[i]);
		if(cc_backup_info.top_c_base[i] != NULL)
			FREE(cc_backup_info.top_c_base[i]);
		if(cc_backup_info.maf_buf_base[i] != NULL)
			FREE(cc_backup_info.maf_buf_base[i]);

		cc_backup_info.top_y_base[i] = NULL;
		cc_backup_info.top_c_base[i] = NULL;
		cc_backup_info.maf_buf_base[i] = NULL;
	}
}

/*
 * return:
 *         TRUE:  backup picture successfully
 *         FALSE: backup picture fail
 */
BOOL cc_backup_picture(void)
{
    struct vpo_io_get_picture_info info_src[2], info_bak;
    enum BACKUP_PIC_RES res[2];
    struct VDec_StatusInfo curStatus = {0};
    int i, ret = TRUE;

    res[0] = CMD_NOT_IMPLEMENT;
    res[1] = CMD_NOT_IMPLEMENT;
    vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);

    if(curStatus.uFirstPicShowed)
    {
        /* i=0: DE_N i=1: DE_O */
        for(i=0; i<2; i++)
        {
            MEMSET(&info_src[i], 0, sizeof(struct vpo_io_get_picture_info));
            info_src[i].de_index = i;
            info_src[i].sw_hw = 0;
            vpo_ioctl((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), VPO_IO_GET_CURRENT_DISPLAY_INFO, &info_src[i]);
            if(info_src[i].status == 0) /* control command is not implemented */
                res[i] = CMD_NOT_IMPLEMENT;
            else if(info_src[i].status == 1) /* control command is implemented but no picture displayed */
                res[i] = NO_PICTURE_SHOWED;
            else if(info_src[i].status == 2) /* control command is implemented and picture info is got */
            {
                if(!info_src[i].y_buf_size || !info_src[i].c_buf_size) /* information is not correct */
                {
                    res[i] = NO_PICTURE_SHOWED;
                    continue;
                }

                /* information is correct, and start to malloc memory */
                res[i] = MALLOC_MEMORY_FAIL;
                do
                {
                    if(cc_backup_info.top_y_base[i] != NULL || cc_backup_info.top_c_base[i] != NULL || cc_backup_info.maf_buf_base[i] != NULL)
                        break;
                    
                    cc_backup_info.top_y_base[i] = cc_backup_malloc(info_src[i].y_buf_size + 256);
                    cc_backup_info.top_c_base[i] = cc_backup_malloc(info_src[i].c_buf_size + 256);
                    
                    if(cc_backup_info.top_y_base[i] == NULL || cc_backup_info.top_c_base[i] == NULL)
                        break;
                    else if((UINT32)cc_backup_info.top_c_base[i] == (info_src[i].top_c&0x8FFFFFFF)
                            || (UINT32)cc_backup_info.top_y_base[i] == (info_src[i].top_y&0x8FFFFFFF))
                        break;

                    if(info_src[i].maf_buf_size)
                    {
                        cc_backup_info.maf_buf_base[i] = cc_backup_malloc(info_src[i].maf_buf_size + 256);
                    }
                    
                    res[i] = MALLOC_MEMORY_OK;
                }while(0);

                if(res[i] == MALLOC_MEMORY_FAIL)
                    break;
            }
        }
    }

    if(res[0] == MALLOC_MEMORY_FAIL || res[1] == MALLOC_MEMORY_FAIL ||
      (res[0] == CMD_NOT_IMPLEMENT && res[1] == CMD_NOT_IMPLEMENT))
    {
        cc_backup_free();

        /* backup picture fail or
           'get current display picture information' is not implemented */
        return FALSE;
    }

    for(i=0; i<2; i++)
    {
        if(res[i] == MALLOC_MEMORY_OK)
        {
            MEMSET(&info_bak, 0, sizeof(struct vpo_io_get_picture_info));
            info_bak.de_index = i;
            info_bak.top_y = ((UINT32)cc_backup_info.top_y_base[i]+255) & 0xFFFFFF00;
            info_bak.top_c = ((UINT32)cc_backup_info.top_c_base[i]+255) & 0xFFFFFF00;
            if(cc_backup_info.maf_buf_base[i] != NULL)
                info_bak.maf_buffer = ((UINT32)cc_backup_info.maf_buf_base[i]+255) & 0xFFFFFF00;
            
            MEMCPY(info_bak.top_y, info_src[i].top_y, info_src[i].y_buf_size);
            MEMCPY(info_bak.top_c, info_src[i].top_c, info_src[i].c_buf_size);
            osal_cache_flush(info_bak.top_y, info_src[i].y_buf_size);
            osal_cache_flush(info_bak.top_c, info_src[i].c_buf_size);

            if(info_src[i].maf_buf_size)
            {
                MEMCPY(info_bak.maf_buffer, info_src[i].maf_buffer, info_src[i].maf_buf_size);
                osal_cache_flush(info_bak.maf_buffer, info_src[i].maf_buf_size);
            }
            
            vpo_ioctl((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS), VPO_IO_BACKUP_CURRENT_PICTURE, &info_bak);
            if(info_bak.status == 0) /* control command is not implemented */
            {
                res[i] = BACKUP_PICTURE_FAIL;
                break;
            }
            else /* control command is implemented */
            {
                res[i] = BACKUP_PICTURE_OK;
            }
        }
    }

    if(res[0] == BACKUP_PICTURE_FAIL || res[1] == BACKUP_PICTURE_FAIL)
    {
        cc_backup_free();

        /* backup picture fail or
           'backup picture' is not implemented */
        return FALSE;
    }

    return TRUE;
}
#endif

static UINT32 current_prog_id = 0xffff;
void api_set_current_prog_id(UINT32 prog_id)
{
    current_prog_id = prog_id;
}

UINT32 get_current_prog_id(void)
{
    return current_prog_id;
}

/* According to cmd_bits, Play All CC Command */
static INT32 cc_driver_act(UINT32 cmd_bits, struct cc_es_info *es, struct cc_device_list *dev_list, struct ft_frontend *ft)
{
	INT32 ret;
   	struct io_param io_parameter;		
	UINT16 pid_list[4];
	UINT16 prog_pos = 0xffff;		
#ifdef CHCHG_TICK_PRINTF
	UINT32 temp_tick = 0;
#endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
	UINT32 ciplus_tmp_tick = 0;
#endif
#ifdef DUAL_VIDEO_OUTPUT
	struct vpo_device *pDisDevice_O = (struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 1);
#endif
	BOOL close_vpo = FALSE, cc_backup_ret = FALSE;
#ifdef CHCHG_TICK_PRINTF
	if(cc_play_tick)
	{
		temp_tick = osal_get_tick();
		libc_printf("####CHCHG %s():line%d start driver act, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
		cc_play_tick = temp_tick;
	}
#endif
	MEMSET(&io_parameter, 0, sizeof(io_parameter));

	if(ft)
	{
		if(ft->xpond.s_info.type == FRONTEND_TYPE_S)
			io_parameter.buff_out_len = PROJECT_FE_DVBS;
	}			
	
	if(es->background_play == 1) //not to operate when start backgound play for dual-record timer
	{
		// set front for backgound play to fix BUG34959
		if ((cmd_bits & CC_CMD_SET_ANTENNA) && ft)
		{
			CC_PRINTF("set antenna for (%d, %d, %d)\n", es->sat_id, es->tp_id, es->prog_id);
			frontend_set_antenna(ft->nim, &ft->antenna, &ft->xpond, 1);
		}

		if ((cmd_bits & CC_CMD_SET_XPOND) && ft)
		{
			CC_PRINTF("set nim for (%d, %d, %d)\n", es->sat_id, es->tp_id, es->prog_id);
			frontend_set_nim(ft->nim, &ft->antenna, &ft->xpond, 1);
		}
		return 0;
	}
	
	//Close Vpo
	CC_PRINTF("CC Driver Act 1 --- Close VPO\n");
	if(cmd_bits&CC_CMD_CLOSE_VPO)
	{
		if(dev_list->vpo)
		{
			//Choose which hardware layer to close: Main Layer or PIP Layer
			UINT32 vpo_layer = es->close_vpo_layer;
       	 	if((es->close_vpo_layer != 0) && (es->close_vpo_layer <= 2))
       	 	{
				vpo_ioctl(dev_list->vpo, VPO_IO_CHOOSE_HW_LAYER, (UINT32)&vpo_layer);
       	 	}
    		ret = vpo_win_onoff(dev_list->vpo, FALSE);
 		}
#ifdef DUAL_VIDEO_OUTPUT
		if(pDisDevice_O)
			vpo_win_onoff(pDisDevice_O, FALSE);	
#endif
#ifdef CHCHG_TICK_PRINTF
		if(cc_play_tick)
		{
			temp_tick = osal_get_tick();
			libc_printf("####CHCHG %s():line%d vpo closed, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
			cc_play_tick = temp_tick;
		}
#endif
	}	
/*
#if (SYS_MAIN_BOARD != BOARD_DB_M3603_01V01 && SYS_MAIN_BOARD != BOARD_DB_M3383_01V01 \
	&& SYS_MAIN_BOARD != BOARD_DB_M3603_02V01&& SYS_MAIN_BOARD !=BOARD_M3383_UM00_01V01)
	*/
#if 1 //(SYS_MAIN_BOARD != BOARD_DB_M3603_01V01 && SYS_MAIN_BOARD != BOARD_DB_M3383_01V01 \
//	&& SYS_MAIN_BOARD != BOARD_DB_M3603_02V01&& SYS_MAIN_BOARD !=BOARD_M3383_UM00_01V01)
   	//Stop Deca Immediately
   	CC_PRINTF("CC Driver Act 2 --- Stop Deca\n");
	if((cmd_bits & CC_CMD_STOP_AUDIO) && (es->audio_no_act == 0))
	{
		if(dev_list->deca)
    	{
    		ret = deca_stop(dev_list->deca, 0, ADEC_STOP_IMM);
    		CC_PRINTF("%s(): deca stop ret = %d\n", __FUNCTION__, ret);
		}
#ifdef CHCHG_TICK_PRINTF
		if(cc_play_tick)
		{
			temp_tick = osal_get_tick();
			libc_printf("####CHCHG %s():line%d deca stop, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
			cc_play_tick = temp_tick;
		}
#endif
	}
#endif	
    
    	//Stop Vdec
    	CC_PRINTF("CC Driver Act 3 --- Stop Vdec\n");
    	if(cmd_bits & CC_CMD_STOP_VIDEO)
    	{

			if(dev_list->vdec_stop == NULL)
				dev_list->vdec_stop = dev_list->vdec;
			if(cmd_bits&CC_CMD_CLOSE_VPO)
				close_vpo = TRUE;
        	if(dev_list->vdec_stop)
        	{    
       		    ret = vdec_stop(dev_list->vdec_stop, close_vpo, FALSE);
	            CC_PRINTF("%s(): vdec stop ret = %d\n", __FUNCTION__, ret);

                #ifdef CHANCHG_VIDEOTYPE_SUPPORT
                if (!pub_blk_scrn &&(SERVICE_TYPE_DTV ==es->service_type))
                {
                    cc_backup_ret = cc_backup_picture();
                    if(!cc_backup_ret)
                    {
                        CC_PRINTF("cc backup pic fail\n");
                    }
                }
                #endif
	        }
			
    		if(dev_list->vdec_hdtv)
			{
		    	if(((es->v_pid) & H264_VIDEO_PID_FLAG) == H264_VIDEO_PID_FLAG)
		    	{
					dev_list->vdec = dev_list->vdec_hdtv;
					video_decoder_select(1, hde_get_mode() == VIEW_MODE_PREVIEW);
		    	}
#ifdef SUPPORT_AVS_DECODER				
				else if (((es->v_pid) & AVS_VIDEO_PID_FLAG) == AVS_VIDEO_PID_FLAG)
		    	{
					dev_list->vdec = dev_list->vdec_hdtv;
					//dev_list->vdec = g_decv_avs_dev;
					video_decoder_select(AVS_DECODER,hde_get_mode() == VIEW_MODE_PREVIEW);
				    //libc_printf("%s: select avs vdec\n",__FUNCTION__);
				}
#endif				
		    	else
		    	{
			    	video_decoder_select(0, hde_get_mode() == VIEW_MODE_PREVIEW);
		    	}
			}
            
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d vdec stop, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
		}		

    	//Pause Vdec
    	CC_PRINTF("CC Driver Act 3-1 --- pause Vdec\n");
    	if(cmd_bits & CC_CMD_PAUSE_VIDEO)
    	{
    		if(dev_list->vdec_hdtv)
			{
		    	if(((es->v_pid) & H264_VIDEO_PID_FLAG) == H264_VIDEO_PID_FLAG)
		    	{
					dev_list->vdec = dev_list->vdec_hdtv;
					video_decoder_select(1, hde_get_mode() == VIEW_MODE_PREVIEW);
		    	}
#ifdef SUPPORT_AVS_DECODER				
			    else if (((es->v_pid) & AVS_VIDEO_PID_FLAG) == AVS_VIDEO_PID_FLAG)
		    	{
					dev_list->vdec = dev_list->vdec_hdtv;
					//dev_list->vdec = g_decv_avs_dev;
					video_decoder_select(AVS_DECODER,hde_get_mode() == VIEW_MODE_PREVIEW);
				    //libc_printf("%s: select avs vdec\n",__FUNCTION__);
			    }
#endif				
		    	else
		    	{
			    	video_decoder_select(0, hde_get_mode() == VIEW_MODE_PREVIEW);
		    	}
			}
			
        	if(dev_list->vdec)
        	{ 
				vdec_io_control(dev_list->vdec, VDEC_IO_KEEP_INPUT_PATH_INFO, TRUE);
        		ret = vdec_stop(dev_list->vdec, FALSE, FALSE);
	            	CC_PRINTF("%s(): vdec stop ret = %d\n", __FUNCTION__, ret);
	       }
		}
    
     	//Stop Dmx Audio and Video
     	CC_PRINTF("CC Driver Act 4 --- Stop Dmx\n");
    	if(cmd_bits & CC_CMD_STOP_DMX)
    	{
#if (defined(PUB_PORTING_PUB29)) && (SYS_PROJECT_FE == PROJECT_FE_DVBT)
			if(ft)
			{
				struct dmx_device* dmx1 = NULL;
				if(ft->ts_route.dmx_id==0)
					dmx1 = dev_get_by_id(HLD_DEV_TYPE_DMX, 1);
				else if(ft->ts_route.dmx_id==1)
					dmx1 = dev_get_by_id(HLD_DEV_TYPE_DMX, 0);
				if(dmx1)
					ret = dmx_io_control(dmx1,IO_STREAM_DISABLE,(UINT32)&io_parameter);
			}
#endif
        	if(dev_list->dmx)
        	{    
#ifdef CC_USE_TSG_PLAYER
				struct ts_route_info ts_route;
				int i;

				for (i = 0; i < CC_MAX_TS_ROUTE_NUM; ++i)
				{
					if ((ts_route_get_by_id(i, &ts_route) == RET_SUCCESS) &&
						(ts_route.ci_mode == CI_SERIAL_MODE) &&
						(ts_route.state & TS_ROUTE_STATUS_USE_CI_PATCH) &&
						(ts_route.state & TS_ROUTE_STATUS_RECORD) &&
						(ts_route.is_recording == 1) &&
						cc_tsg_task_is_running())
					{
						break; /* recording using CI patch, not stop patch */
					}
				}
				
				if (i >= CC_MAX_TS_ROUTE_NUM)
				{
					//bypass all first
#ifdef CI_SUPPORT					
					api_set_nim_ts_type(2, 0x03);
#endif
					//then stop patch
					cc_stop_patch();
				}
#endif

            	ret = dmx_io_control(dev_list->dmx, es->dmx_2play ? IO_STREAM_DISABLE_EXT : IO_STREAM_DISABLE, (UINT32)&io_parameter);
            	CC_PRINTF("%s(): stop dmx av ret = %d\n", __FUNCTION__, ret);
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d dmx stop, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
    	}

        if(cmd_bits & CC_CMD_DMX_DISABLE)
        {           
        	if(dev_list->dmx)
        	{
            	ret = dmx_io_control(dev_list->dmx, es->dmx_2play ? IO_STREAM_DISABLE_EXT : IO_STREAM_DISABLE, 0);
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d dmx disable, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
        }

		if(cmd_bits & CC_CMD_STOP_MCAS_SERVICE )
		{
#ifdef MULTI_CAS
#ifdef NEW_DEMO_FRAME
#ifdef COMBO_CA_PVR 
		if((ft->ts_route.dmx_id == 1) && (ts_route_check_recording_by_nim_id(0) != RET_SUCCESS)) 
#endif
	    {
            #ifndef MULTI_DESCRAMBLE
        	#if (CAS_TYPE == CAS_ABEL)
			api_mcas_stop_service();
		#else
        	api_mcas_stop_service(es->sim_id);
            #endif
            #endif
        }
#else
		    api_mcas_stop_service();
#endif
	    	if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
	    	{
				#if (defined(GET_CAT_BY_SIM)) && (defined(NEW_DEMO_FRAME))
				api_mcas_stop_transponder(es->sim_id);
				#else
                    #ifdef MULTI_DESCRAMBLE
                    if(api_mcas_get_prog_record_flag(es->prog_id) == FALSE)   //if the program is recording,don't stop descramble service
                        api_mcas_stop_transponder_multi_des(ft->ts_route.dmx_id-1);
                    #else
    	    		api_mcas_stop_transponder();
				#ifdef SUPPORT_CAS_A
				sie_stop_emm_service();
				#endif
    				#endif
				#endif
	    	}
#endif
#if defined(SUPPORT_VMX_STD) && !defined(VMX_NEW_CC)
			//libc_printf("cc_driver_act:api_mcas_stop_service\n");
		    api_mcas_stop_service();
			#if !(defined(VMX_PATCH_CC))
			osal_task_sleep(500);
			#endif
	    	if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
	    	{
	    		//libc_printf("cc_driver_act:api_mcas_stop_transponder\n");
	    		api_mcas_stop_transponder();
	    	}
			#if !(defined(VMX_PATCH_CC))
			osal_task_sleep(500);
			#endif
#elif defined(SUPPORT_VMX) || defined(VMX_NEW_CC)
	    	if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
	    	{
				UINT8 dmx_id = 0;

				#ifdef VMX_PVR_SUPPORT
	    		//libc_printf("cc_driver_act:api_mcas_stop_transponder(g_pre_nim_id = %d)\n", g_pre_nim_id);
	    		dmx_id = g_pre_nim_id;
				#endif
	    		api_mcas_stop_transponder_multi_des(dmx_id);
	    	}
#endif
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d mcas stop, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
		}


	    //Fill Frame Buffer with Color
	    CC_PRINTF("CC Driver Act 5 --- Fill Frame Buffer\n");
    	if((cmd_bits & CC_CMD_FILL_FB) && enable_blk_screen)
    	{
        	if(dev_list->vdec)
        	{    
        		struct YCbCrColor tColor;
        		tColor.uY = 0x10;
        		tColor.uCb = 0x80;
        		tColor.uCr = 0x80;
        		ret = vdec_io_control(dev_list->vdec, VDEC_IO_FILL_FRM, (UINT32)&tColor);
        		CC_PRINTF("%s(): fill frame buffer ret = %d\n", __FUNCTION__, ret);
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d fill framebuffer, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
    	}

		//set front
		if(cmd_bits & CC_CMD_SET_ANTENNA )
		{
			if(ft)
				frontend_set_antenna(ft->nim, &ft->antenna, &ft->xpond, 1);
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d antenna set, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
		}

		if(cmd_bits & CC_CMD_SET_XPOND )
		{
			if(ft)
			{
				frontend_set_nim(ft->nim, &ft->antenna, &ft->xpond, 1);
           		//After Set Front End, Enable TDT Parse, not to do under S
            	if(ft->xpond.s_info.type != FRONTEND_TYPE_S)
            	{
        		;  //enable_time_parse();
            	}
#ifdef PUB_PORTING_PUB29
#if (SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC))
				if((lib_nimng_get_nim_rec()==0)&&(lib_nimng_get_lnb_ns() >1))
				{
					UINT8 nim_play_id = 0; 
					struct nim_device *nim_rec = NULL;
					
					nim_play_id	=lib_nimng_get_nim_play();										
					if(nim_play_id==1)
						nim_rec = (struct nim_device *)dev_get_by_id(HLD_DEV_TYPE_NIM, 1);
					else if(nim_play_id==2)
						nim_rec = (struct nim_device *)dev_get_by_id(HLD_DEV_TYPE_NIM, 0);

					if(nim_rec)
						frontend_set_nim(nim_rec, &ft->antenna, &ft->xpond, 1);					
				}
#endif
#endif
			}			
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d xpond set, tick=%d, tick used=%d\n", __FUNCTION__,__LINE__,temp_tick,temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
		}
/*
#if (SYS_MAIN_BOARD == BOARD_DB_M3603_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3383_01V01 \
	|| SYS_MAIN_BOARD == BOARD_DB_M3603_02V01|| SYS_MAIN_BOARD ==BOARD_M3383_UM00_01V01)
*/
#if 0//(SYS_MAIN_BOARD == BOARD_DB_M3603_01V01 || SYS_MAIN_BOARD == BOARD_DB_M3383_01V01 \
	//|| SYS_MAIN_BOARD == BOARD_DB_M3603_02V01|| SYS_MAIN_BOARD ==BOARD_M3383_UM00_01V01)
   	//Stop Deca Immediately
   	CC_PRINTF("CC Driver Act 2 --- Stop Deca\n");
	if((cmd_bits & CC_CMD_STOP_AUDIO) && (es->audio_no_act == 0))
	{
		if(dev_list->deca)
    	{
    		ret = deca_stop(dev_list->deca, 0, ADEC_STOP_IMM);
        		CC_PRINTF("%s(): deca stop ret = %d\n", __FUNCTION__, ret);
	    }
#ifdef CHCHG_TICK_PRINTF
		if(cc_play_tick)
		{
			temp_tick = osal_get_tick();
			libc_printf("####CHCHG %s():line%d deca stop, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
			cc_play_tick = temp_tick;
		}
#endif
	}
#endif
	if(cmd_bits & CC_CMD_START_SI_MONITOR )
	{
		prog_pos = get_prog_pos(es->prog_id);
#ifdef AUTO_OTA
		si_set_default_dmx(dev_list->dmx->type&HLD_DEV_ID_MASK);
		ota_monitor_on(prog_pos);
#endif // AUTO_OTA
//#ifndef NEW_DEMO_FRAME //Temp Solution For PIP PVR new SI Monitor
#if ((SYS_PROJECT_FE == PROJECT_FE_ATSC) || (SYS_PROJECT_FE == PROJECT_FE_DVBT))
	    si_monitor_on(prog_pos);
		
#if(defined(_SERVICE_NAME_UPDATE_ENABLE_)\
||defined(_MULTILINGAL_SERVICE_NAME_ENABLE_)\
||defined(_PREFERRED_NAME_ENABLE_)\
||defined(_SHORT_SERVICE_NAME_ENABLE_))
#if (SYS_PROJECT_FE != PROJECT_FE_ATSC)
#ifdef _DTGSI_ENABLE_
	#ifdef SUPPORT_FRANCE_HD
		extern UINT8 sdt_trigge_channel_change;
		extern UINT16 prev_index;

		if((sdt_trigge_channel_change==TRUE))
		{		
			sdt_other_monitor_on(prev_index);
			sdt_trigge_channel_change=FALSE;
		}
		else
		{
			sdt_monitor_on(prog_pos);
		}
	#else // SUPPORT_FRANCE_HD
		//sdt_monitor_on();
		sdt_monitor_on(prog_pos);
	#endif // SUPPORT_FRANCE_HD
#endif // _DTGSI_ENABLE_
#endif // (SYS_PROJECT_FE != PROJECT_FE_ATSC)
#endif
#ifdef SUPPORT_FRANCE_HD
		nit_monitor_on();
#endif // SUPPORT_FRANCE_HD

#else
		if (es->sim_onoff_enable)
			cc_sim_start_monitor(es, dev_list->dmx);
/* fixed:BUG39541
 * add condition:  && !defined(NEW_DEMO_FRAME)
 * because sabbat dual CI+ project should not open/close simonitor in libpub
 */
#if defined(CONAX_NEW_PUB) || (defined(_MHEG5_V20_ENABLE_) && !defined(NEW_DEMO_FRAME))
		prog_pos = get_prog_pos(es->prog_id);
	    	si_monitor_on(prog_pos);
#endif
//PVR defined NEW_DEMO_FRAME, call cc_sim_start_monitor(),but CAS need si_monitor_on()
	#if(CAS_TYPE==CAS_CDCA3||CAS_TYPE == CAS_TF||CAS_TYPE == CAS_CDCA||CAS_TYPE==CAS_GOS)
		prog_pos = get_prog_pos(es->prog_id);
	    si_monitor_on(prog_pos);
	#endif
#endif

#ifdef MULTI_CAS
            P_NODE tmp_cas_node;
		    get_prog_by_id(es->prog_id, &tmp_cas_node);
		if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ) || mcas_xpond_stoped)
		{
           // P_NODE tmp_cas_node;
		    get_prog_by_id(es->prog_id, &tmp_cas_node);
#if (defined(GET_CAT_BY_SIM)) && (defined(NEW_DEMO_FRAME))
            //if(tmp_cas_node.ca_mode == 1)
            {
			    api_mcas_start_transponder(es->sim_id);
            }
#else
		#ifdef SUPPORT_CAS_A
			api_set_dmx_device(dev_list->dmx);
			api_mcas_start_transponder();
			sie_start_emm_service();
		#else
            //if(tmp_cas_node.ca_mode == 1)
            {
                #ifdef MULTI_DESCRAMBLE
                api_mcas_start_transponder_multi_des(ft->ts_route.dmx_id-1);
                #else
			    api_mcas_start_transponder();
                #endif
            }
#endif
#endif
                        mcas_xpond_stoped = FALSE;
		}
#ifdef SUPPORT_HW_CONAX
		//P_NODE tmp_cas_node;
		get_prog_by_id(es->prog_id, &tmp_cas_node);
#ifdef SUPPORT_CAS9
#ifdef COMBO_CA_PVR
	if((ft->ts_route.dmx_id == 1) &&  (ts_route_check_recording_by_nim_id(0) != RET_SUCCESS))
#else
        //if(tmp_cas_node.ca_mode == 1)
#endif
        {
    		ca_service_info cas_info;
    		MEMSET(&cas_info, 0, sizeof(cas_info));
    		cas_info.prog_number = tmp_cas_node.prog_number;
    		cas_info.video_pid = tmp_cas_node.video_pid;
    		cas_info.cur_audio = tmp_cas_node.cur_audio;
    		
    		if(tmp_cas_node.audio_count>MAX_CA_AUDIO_CNT)
    			cas_info.audio_count = MAX_CA_AUDIO_CNT;
    		else
    			cas_info.audio_count = tmp_cas_node.audio_count;

    		MEMCPY(&cas_info.audio_pid[0], &tmp_cas_node.audio_pid[0], sizeof(UINT16)*cas_info.audio_count);

    		cas_info.subtitle_pid = tmp_cas_node.subtitle_pid;
    		cas_info.teletext_pid = tmp_cas_node.teletext_pid;
    		ca_set_prog_info(&cas_info);
		}
#else
		#ifndef SUPPORT_CAS7
		mcas_set_prog_info(&tmp_cas_node);
		#endif
#endif
#endif		
#ifdef SUPPORT_CAS7 //notify lib  interesting pids info 
		get_prog_by_id(es->prog_id, &tmp_cas_node);
		ca_service_info cas_info;
		MEMSET(&cas_info, 0, sizeof(cas_info));
		cas_info.prog_number = tmp_cas_node.prog_number;
		cas_info.video_pid = tmp_cas_node.video_pid;
		cas_info.cur_audio = tmp_cas_node.cur_audio;

		if(tmp_cas_node.audio_count>MAX_CA_AUDIO_CNT)
		cas_info.audio_count = MAX_CA_AUDIO_CNT;
		else
		cas_info.audio_count = tmp_cas_node.audio_count;

		MEMCPY(&cas_info.audio_pid[0], &tmp_cas_node.audio_pid[0], sizeof(UINT16)*cas_info.audio_count);

		cas_info.subtitle_pid = tmp_cas_node.subtitle_pid;
		cas_info.teletext_pid = tmp_cas_node.teletext_pid;
		#ifdef CONAX7_SPORT_MULTIDMX
		#if 0
		dmx_ca_set_prog_info(dev_list->dmx,&cas_info);
		#else
		struct io_param param_ca ;
		MEMSET(&param_ca,0,sizeof(param_ca));
		param_ca.io_buff_in = &cas_info; 
		ret = dmx_io_control(dev_list->dmx, IO_DMX_CA_SET_PIDS, &param_ca); 
		#endif
		#endif
#endif
#ifdef NEW_DEMO_FRAME
#ifdef COMBO_CA_PVR
        if((ft->ts_route.dmx_id == 1) &&  (ts_route_check_recording_by_nim_id(0) != RET_SUCCESS)) 
#else
	#if(CAS_TYPE==CAS_ABEL)
	 #else
        //if(tmp_cas_node.ca_mode == 1)
#endif
#endif

        {
            #ifdef MULTI_DESCRAMBLE
            //libc_printf("%s,es->prog_id=%d,current prog_id=%d\n",__FUNCTION__,es->prog_id,get_current_prog_id());
            //if(es->prog_id == get_current_prog_id()) //fixed bug:quickly change channel,the APP channel num has been changed;
            {
                // @HM_CONAX3515
                api_mcas_start_service_multi_des(es->prog_id, es->sim_id, ft->ts_route.dmx_id-1);
            }
            #else
		#if (CAS_TYPE == CAS_ABEL)
			P_NODE tmp_node;
		      	get_prog_by_id(es->prog_id, &tmp_node);
		     	api_mcas_pmt_pid(tmp_node.pmt_pid);	
			api_mcas_start_service(es->prog_id);
		#else
            //libc_printf("%s,es->prog_id=%d,es->sim_id=%d\n",__FUNCTION__,es->prog_id,es->sim_id);		

	#ifdef SAT2IP_CLIENT_SUPPORT
		struct ts_route_info satip_ts_route;
		MEMSET(&satip_ts_route, 0x0, sizeof(struct ts_route_info));
		ts_route_get_by_sat2ip(&satip_ts_route);
		if (satip_ts_route.prog_id != es->prog_id)
	#endif
		    api_mcas_start_service(es->prog_id, es->sim_id);
            #endif
            #endif
        }
#else
        //if(tmp_cas_node.ca_mode == 1)
        {
		    api_mcas_start_service(es->prog_id);
        }
#endif
#endif  /* end of MULTI_CAS */

#if defined(SUPPORT_VMX_STD) && !defined(VMX_NEW_CC) //CAS_CM_ENABLE
		//?? check 
#if 1//modify for stop transponder issue
	if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
	{
		//libc_printf("cc_driver_act:api_mcas_start_transponder\n");
		api_mcas_start_transponder();
	}
#else
	P_NODE tmp_cas_node;
	get_prog_by_id(es->prog_id, &tmp_cas_node);
	if(tmp_cas_node.ca_mode == 1)
		{
		//libc_printf("cc_driver_act:api_mcas_start_transponder\n");
		api_mcas_start_transponder();
		}
#endif

	#if defined(SUPPORT_VMX_STD)  /* support VMX STD record 2 voice */
	P_NODE tmp_cas_node;
	get_prog_by_id(es->prog_id, &tmp_cas_node);

	ca_service_info cas_info;
	MEMSET(&cas_info, 0, sizeof(cas_info));
	cas_info.prog_number = tmp_cas_node.prog_number;
	cas_info.video_pid = tmp_cas_node.video_pid;
	cas_info.cur_audio = tmp_cas_node.cur_audio;

	if(tmp_cas_node.audio_count>MAX_CA_AUDIO_CNT)
	{
		cas_info.audio_count = MAX_CA_AUDIO_CNT;
	}
	else
	{
		cas_info.audio_count = tmp_cas_node.audio_count;
	}

	MEMCPY(&cas_info.audio_pid[0], &tmp_cas_node.audio_pid[0], sizeof(UINT16)*cas_info.audio_count);

	cas_info.subtitle_pid = tmp_cas_node.subtitle_pid;
	cas_info.teletext_pid = tmp_cas_node.teletext_pid;

	//libc_printf("%s(): prog_number=%u, video_pid=0x%x, cur_audio=0x%x, audio_count=%u\n",__FUNCTION__,cas_info.prog_number,cas_info.video_pid,cas_info.cur_audio,cas_info.audio_count);
	//libc_printf("%s(): get correct audio pid, audio_count=%u \n",__FUNCTION__,cas_info.audio_count);
	int i = 0;
	/* get correct audio pid */
	for(i=0;i<cas_info.audio_count;i++)
	{
		cas_info.audio_pid[i] &= 0x1FFF;
	}

	#if 0
	dmx_ca_set_prog_info(dev_list->dmx,&cas_info);
	#else
	struct io_param param_ca ;
	MEMSET(&param_ca,0,sizeof(param_ca));
	param_ca.io_buff_in = &cas_info; 
	ret = dmx_io_control(dev_list->dmx, IO_DMX_CA_SET_PIDS, &param_ca); 
	#endif
	#endif	// end of SUPPORT_VMX_STD record 2 audio track

    #if defined(VMX_PATCH_CC)
		VMX_API_PRINTF("cc_driver_act:api_mcas_start_service es->service_id=%d\n",es->service_id);//change to service id
		api_mcas_start_service(es->service_id);//change to service id
    #else
	//libc_printf("cc_driver_act:api_mcas_start_service\n");
	api_mcas_start_service(es->prog_id);	
	#endif
#elif defined(SUPPORT_VMX) || defined(VMX_NEW_CC)
	if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
	{
		UINT8 dmx_id = 0;

		dmx_id = ft->ts_route.dmx_id-1;
		api_mcas_start_transponder_multi_des(dmx_id);
	}
#endif

#if (CAS_TYPE == CAS_IRDETO)
		if((cmd_bits & CC_CMD_SET_ANTENNA )||(cmd_bits & CC_CMD_SET_XPOND ))
		{
#if (defined(GET_CAT_BY_SIM)) && (defined(NEW_DEMO_FRAME))
			api_mcas_start_transponder(es->sim_id);
#else
			api_mcas_start_transponder();
#endif
		}
#ifdef NEW_DEMO_FRAME
		api_mcas_start_service(es->prog_id, es->sim_id);
#else
		api_mcas_start_service(es->prog_id);
#endif


#endif
#ifdef CHCHG_TICK_PRINTF
		if(cc_play_tick)
		{
			temp_tick = osal_get_tick();
			libc_printf("####CHCHG %s():line%d monitor and mcas start, tick=%d, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick,temp_tick-cc_play_tick);
			cc_play_tick = temp_tick;
		}
#endif
	}
	
 #ifdef CHANNEL_CHANGE_VIDEO_FAST_SHOW
	if(cmd_bits & CC_CMD_INFO_VPO_CHANCHNG)
	{
		if(hde_get_mode()==VIEW_MODE_MULTI)
			vpo_ioctl((struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 0),VPO_IO_CHANGE_CHANNEL, 0);
		else
			vpo_ioctl((struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 0),VPO_IO_CHANGE_CHANNEL, 1);
#ifdef CHCHG_TICK_PRINTF
		if(cc_play_tick)
		{
			temp_tick = osal_get_tick();
			libc_printf("####CHCHG %s():line%d DIS change channel, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
			cc_play_tick = temp_tick;
		}
#endif
			
	}
#endif
    	//Start Vdec
    	CC_PRINTF("CC Driver Act 7 --- Start Vdec\n");
    	if(cmd_bits & CC_CMD_START_VIDEO)
    	{
       	    if(dev_list->vdec)
        	{    
                #ifdef CHANCHG_VIDEOTYPE_SUPPORT
        		if (!pub_blk_scrn && cc_backup_ret)
        		{
        			struct vdec_io_reg_callback_para cc_backup_para;
        			cc_backup_para.eCBType = VDEC_CB_FIRST_SHOWED;
        			cc_backup_para.pCB = cb_vdec_first_show;
        			vdec_io_control(dev_list->vdec, VDEC_IO_REG_CALLBACK, (UINT32)(&cc_backup_para));
        		}
                #endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
				{
        			struct vdec_io_reg_callback_para cc_backup_para;
        			cc_backup_para.eCBType = VDEC_CB_FIRST_SHOWED;
        			cc_backup_para.pCB = cb_vdec_first_show;
        			vdec_io_control(dev_list->vdec, VDEC_IO_REG_CALLBACK, (UINT32)(&cc_backup_para));
				}
#endif
                
           		ret = vdec_start(dev_list->vdec);
            	CC_PRINTF("%s(): vdec start ret = %d\n", __FUNCTION__, ret);
        	}
            
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				vdec_start_tick = temp_tick;
				libc_printf("####CHCHG %s():line%d vdec start, tick=%d, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
        	if(ciplus_cc_begin_tick)
			{
				ciplus_tmp_tick = osal_get_tick();
				libc_printf("#\t Vdec Start (@%s)\n", __FUNCTION__);
				libc_printf("#\t tic = %d, tic used = %d, gap = %d\n", ciplus_tmp_tick, ciplus_tmp_tick-ciplus_cc_begin_tick, ciplus_tmp_tick-ciplus_cc_prev_tick);
				ciplus_cc_prev_tick = ciplus_tmp_tick;
			}
#endif
    	}

    	//Resume Vdec
    	CC_PRINTF("CC Driver Act 7-1 --- resume Vdec\n");
    	if(cmd_bits & CC_CMD_RESUME_VIDEO)
    	{			
        	if(dev_list->vdec)
        	{    
        		ret = vdec_dvr_resume(dev_list->vdec);
	            CC_PRINTF("%s(): vdec resume ret = %d\n", __FUNCTION__, ret);
	        }
		}
    
    	//Start Deca
    	CC_PRINTF("CC Driver Act 8 --- Start Deca\n");
    	if((cmd_bits & CC_CMD_START_AUDIO) && (es->audio_no_act == 0))
    	{
        	if((dev_list->deca) && (dev_list->snd_dev))
        	{
        		//Set Audio Stream Type in Deca
        		deca_io_control(dev_list->deca, DECA_SET_STR_TYPE, es->a_type);
			
        		//Set Spdif Type in Snd
        		if(es->spdif_enable)
        		{                      
            		//if(es->a_type == AUDIO_AC3)
            		if( (es->a_type == AUDIO_AC3)||
                        (es->a_type == AUDIO_EC3) ||
                		(es->a_type == AUDIO_MPEG_AAC) ||
                		(es->a_type == AUDIO_MPEG_ADTS_AAC))

            		{
                		snd_set_spdif_type(dev_list->snd_dev, SND_OUT_SPDIF_BS);
            		}
            		else if(es->a_type == AUDIO_MPEG2)
            		{
                		snd_set_spdif_type(dev_list->snd_dev, SND_OUT_SPDIF_PCM);
            		}
        		}
					
			    //Call CAT driver to Disable Audio
        		//if(es->a_type == AUDIO_AC3)
        		if( (es->a_type == AUDIO_AC3)||
                    (es->a_type == AUDIO_EC3) ||
            		(es->a_type == AUDIO_MPEG_AAC) ||
            		(es->a_type == AUDIO_MPEG_ADTS_AAC))
	     		{	     			
	     			CC_PRINTF("Play Channel Disable Audio.\n");
				set_hdmi_audio_output(FALSE);
	     		}
					
      			//Start Deca
            		ret = deca_start(dev_list->deca, 0);
            		CC_PRINTF("%s(): deca start ret = %d\n", __FUNCTION__, ret);
					
			    //Call CAT driver to Enable Audio
	     		if(es->a_type == AUDIO_MPEG2)
	     		{	     			
	     			CC_PRINTF("Play Channel Enable Audio.\n");
				set_hdmi_audio_output(TRUE);
	     		}
				
	            //Set Audio Channel
            	set_audio_channel(dev_list->snd_dev, es->a_ch);  

    			//set snd volumn
    			/* If Current Mode is Mute, can not Set Volumn */
    			if(SUCCESS !=  snd_io_control(dev_list->snd_dev, IS_SND_MUTE, 0))
    			{
    				snd_set_volume(dev_list->snd_dev, SND_SUB_OUT, es->a_volumn);
    			}
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d deca start, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
        	if(ciplus_cc_begin_tick)
			{
				ciplus_tmp_tick = osal_get_tick();
				libc_printf("#\t Adec Start (@%s)\n", __FUNCTION__);
				libc_printf("#\t tic = %d, tic used = %d, gap = %d\n", ciplus_tmp_tick, ciplus_tmp_tick-ciplus_cc_begin_tick, ciplus_tmp_tick-ciplus_cc_prev_tick);
				ciplus_cc_prev_tick = ciplus_tmp_tick;
			}
#endif
    	}

 //move start dmx after vdec start and deca start 
  	//Start Dmx Es Stream
    	CC_PRINTF("CC Driver Act 6 --- Start Dmx\n");
    	if(cmd_bits & CC_CMD_START_DMX)
    	{
        	UINT32 create_stream = 0;
        	UINT32 enable_stream = 0;

		//Video PID, Audio PID and PCR PID
        	MEMSET(&pid_list[0], 0, sizeof(pid_list));
        	io_parameter.io_buff_in = (UINT8 *)pid_list;
			io_parameter.buff_in_len = sizeof(pid_list);
        	if(cmd_bits & CC_CMD_START_VIDEO)
        	{
        		pid_list[0] = es->v_pid;
        	}
        	if(cmd_bits & CC_CMD_START_AUDIO)
        	{
        		pid_list[1] = es->a_pid;
#ifdef AUDIO_DESCRIPTION_SUPPORT
				pid_list[3] = es->ad_pid;
#else
				pid_list[3] = INVALID_PID;
#endif
        	}
#if (defined(_MHEG5_ENABLE_) || defined(_MHEG5_V20_ENABLE_) )
			else
				pid_list[1] = INVALID_PID; //_MHEG5_ENABLE_
#endif
			
         	pid_list[2] = es->pcr_pid;

		//Create Audio Stream or/and Video Stream
        	if((cmd_bits & CC_CMD_START_AUDIO) && (cmd_bits & CC_CMD_START_VIDEO))
        	{
        		create_stream = es->dmx_2play ? IO_CREATE_AV_STREAM_EXT : IO_CREATE_AV_STREAM;
        		enable_stream = es->dmx_2play ? IO_STREAM_ENABLE_EXT : IO_STREAM_ENABLE;
        	}
        	else if(cmd_bits & CC_CMD_START_AUDIO)
        	{
        		create_stream = IO_CREATE_AUDIO_STREAM;
        		enable_stream = AUDIO_STREAM_ENABLE;
        	}
        	else if(cmd_bits & CC_CMD_START_VIDEO)
        	{
#if (defined(_MHEG5_ENABLE_) || defined(_MHEG5_V20_ENABLE_) )
				create_stream = IO_CREATE_AV_STREAM;
				enable_stream = IO_STREAM_ENABLE;
#else
        		create_stream = IO_CREATE_VIDEO_STREAM;
        		enable_stream = IO_STREAM_ENABLE;
#endif
        	}

        	if((create_stream != 0) && (enable_stream != 0))
        	{
			//force to change slot for dynamic pid
			if (es->dynamic_pid_chgch == 1)
			{
				ret = dmx_io_control(dev_list->dmx,DMX_FORCE_CHANGE_SLOT,(UINT32)NULL);
				CC_PRINTF("DMX_FORCE_CHANGE_SLOT : %s :dmx force to cahnge stream slot ,ret = %d\n", __FUNCTION__,ret);
			}			
			
    		ret = dmx_io_control(dev_list->dmx, create_stream, (UINT32)&io_parameter);
    		CC_PRINTF("%s(): dmx create stream,v[%d]a[%d]p[%d], ret = %d\n", __FUNCTION__,
    			pid_list[0],pid_list[1],pid_list[2],ret);

	        //Set Audio Synchronization mode in Deca
    		if(INVALID_PID != es->v_pid)
    		{
        		deca_set_sync_mode(dev_list->deca, ADEC_SYNC_PTS);
    		}
    		else 
    		{
        		deca_set_sync_mode(dev_list->deca, ADEC_SYNC_FREERUN);
    		}								
			
	        //Enable Dmx Stream
			if((enable_stream==IO_STREAM_ENABLE) || (enable_stream==IO_STREAM_ENABLE_EXT)
				|| (enable_stream==VIDEO_STREAM_ENABLE) || (enable_stream==AUDIO_STREAM_ENABLE))
			{
				struct dmx_device *dmx = dev_get_by_id(HLD_DEV_TYPE_DMX, 0);

				if(dev_list->dmx != dmx)
				{
					if(dmx_io_control(dmx, CHECK_VDEC_OCCUPATION, 0) == RET_SUCCESS
						|| dmx_io_control(dmx, CHECK_ADEC_OCCUPATION, 0) == RET_SUCCESS)
					{
						dmx_io_control(dev_get_by_id(HLD_DEV_TYPE_DMX, 0), IO_STREAM_DISABLE, (UINT32)NULL);
					}
				}
				else
				{
					if(dmx_io_control(dev_get_by_id(HLD_DEV_TYPE_DMX, 1), CHECK_VDEC_OCCUPATION, 0) == RET_SUCCESS
						||dmx_io_control(dev_get_by_id(HLD_DEV_TYPE_DMX, 1), CHECK_ADEC_OCCUPATION, 0) == RET_SUCCESS)
					{
							dmx_io_control(dev_get_by_id(HLD_DEV_TYPE_DMX, 1), IO_STREAM_DISABLE, (UINT32)NULL);
					}
				}
			}
    		ret = dmx_io_control(dev_list->dmx, enable_stream, (UINT32)&io_parameter);
    		CC_PRINTF("%s(): dmx enable stream,ret = %d\n", __FUNCTION__,ret);
        	}
#ifdef CHCHG_TICK_PRINTF
        	if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d dmx start, tick=%d,tick used=%d\n", __FUNCTION__,__LINE__, temp_tick,temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
        	if(ciplus_cc_begin_tick)
			{
				ciplus_tmp_tick = osal_get_tick();
				libc_printf("#\t DMX Start (@%s)\n", __FUNCTION__);
				libc_printf("#\t tic = %d, tic used = %d, gap = %d\n", ciplus_tmp_tick, ciplus_tmp_tick-ciplus_cc_begin_tick, ciplus_tmp_tick-ciplus_cc_prev_tick);
				ciplus_cc_prev_tick = ciplus_tmp_tick;
			}
#endif
    	}

    	
    	//Change Dmx Audio Stream
    	CC_PRINTF("CC Driver Act 9 --- Change Audio PID\n");
    	if(cmd_bits & CC_CMD_DMX_CHG_APID)
    	{
        	if(dev_list->dmx)
        	{    
        		MEMSET(&pid_list[0], 0, sizeof(pid_list));
        		io_parameter.io_buff_in = (UINT8 *)pid_list;
				io_parameter.buff_in_len = sizeof(pid_list);
        		pid_list[1] = es->a_pid;
#ifdef AUDIO_DESCRIPTION_SUPPORT
        		pid_list[3] = es->ad_pid;
#else
				pid_list[3] = INVALID_PID;
#endif
        		ret = dmx_io_control(dev_list->dmx, IO_CHANGE_AUDIO_STREAM, (UINT32)&io_parameter);
        		CC_PRINTF("%s(): change audio pid ret = %d\n", __FUNCTION__, ret);
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d dmx change audio pid, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
    	}    

	    //Switch Audio Channel
	    CC_PRINTF("CC Driver Act 10 --- Switch Audio Channel\n");
    	if(cmd_bits & CC_CMD_AUDIO_SWITCH_CHAN)
    	{
        	if(dev_list->snd_dev)
        	{
            	set_audio_channel(dev_list->snd_dev, es->a_ch);
        	}
#ifdef CHCHG_TICK_PRINTF
			if(cc_play_tick)
			{
				temp_tick = osal_get_tick();
				libc_printf("####CHCHG %s():line%d switch audio channel, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick-cc_play_tick);
				cc_play_tick = temp_tick;
			}
#endif
    	}

	    CC_PRINTF("CC Driver Act 11 --- Leave Driver Act\n");
}

/* Switch Audio PID *
 * For example, one program may have several language streams, when switch another language stream,
 * this function will be called by upper layer. */
static void cc_switch_apid(UINT32 cmd, struct cc_es_info *es, struct cc_device_list *dev_list)
{
    	UINT32 cmd_bits = cmd;

    	if(es->a_pid != 0)
    	{
        	cmd_bits = CC_CMD_STOP_AUDIO|CC_CMD_DMX_CHG_APID|CC_CMD_START_AUDIO;
    	}
    	else
    	{
        	cmd_bits = CC_CMD_NULL;
	}
    	cc_driver_act(cmd_bits, es, dev_list, NULL);
}

/* Pause Video, don't Pause Audio */
static void cc_pause_video(UINT32 cmd, struct cc_es_info *es, struct cc_device_list *dev_list)
{
    	UINT32 cmd_bits = cmd;

    	cmd_bits = CC_CMD_PAUSE_VIDEO;//CC_CMD_STOP_VIDEO;
    	cc_driver_act(cmd_bits,es, dev_list, NULL);
}

/* Resume Video*/
static void cc_resume_video(UINT32 cmd, struct cc_es_info *es, struct cc_device_list *dev_list)
{
    	UINT32 cmd_bits = cmd;

    	cmd_bits = CC_CMD_START_VIDEO;
    	cc_driver_act(cmd_bits,es, dev_list, NULL);
}

static BOOL is_vdec_first_shown = FALSE;
/* First Video Frame Already Show */
static void cb_vdec_first_show(UINT32 uParam1, UINT32 uParam2)
{
	is_vdec_first_shown = TRUE;
#ifdef CHANCHG_VIDEOTYPE_SUPPORT
    cc_backup_free();
#endif
#ifdef CHCHG_TICK_PRINTF
	if(vdec_start_tick)
	{
		UINT32 temp_tick = osal_get_tick();
		libc_printf("####CHCHG %s():line%d vdec first show, tick=%d, tick used=%d\n", __FUNCTION__,__LINE__, temp_tick, temp_tick-vdec_start_tick);
		vdec_start_tick = 0;
	}
#endif
#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
	UINT32 ciplus_tmp_tick = osal_get_tick();
	libc_printf("# First Picture Show (@%s)\n", __FUNCTION__);
	libc_printf("#\t tic = %d, tic used = %d, gap = %d\n", ciplus_tmp_tick, ciplus_tmp_tick-ciplus_cc_begin_tick, ciplus_tmp_tick-ciplus_cc_prev_tick);
	ciplus_cc_prev_tick = ciplus_tmp_tick;
#endif
}

/* Check whether First Vedio Frame Already Show or not */
static BOOL ck_vdec_first_show(void)
{
	return is_vdec_first_shown;
}

/* Reset First Vedio Frame not Show */
static void reset_vdec_first_show(void)
{
	is_vdec_first_shown = FALSE;
}

extern UINT32 CIPlus_case_idx;
/* Process Before Play Channel */
static void cc_pre_play_channel(struct dmx_device *dmx, struct cc_es_info *es,
					struct ft_ts_route *ts_route, UINT8 frontend_change)
{
	UINT16 prog_pos = 0xffff;
	T_NODE tp;
	struct ci_service_info service;

#if (defined(_MHEG5_V20_ENABLE_) )
	MHEG5_ReceiverStopApplications();
#endif
     	//Stop CA
     	CC_PRINTF("CC Pre Play Channel 1 --- Stop CA\n");


    	//SI Monitor Off
    	CC_PRINTF("CC Pre Play Channel 3 --- SI Monitor Off\n");    	
#ifndef NEW_DEMO_FRAME //Temp Solution For PIP PVR new SI Monitor
	prog_pos = get_prog_pos(es->prog_id);
    	si_monitor_off(prog_pos);
#if(defined(_SERVICE_NAME_UPDATE_ENABLE_)\
	||defined(_MULTILINGAL_SERVICE_NAME_ENABLE_)\
	||defined(_PREFERRED_NAME_ENABLE_)\
	||defined(_SHORT_SERVICE_NAME_ENABLE_))
#if (SYS_PROJECT_FE != PROJECT_FE_ATSC)
	sdt_monitor_off();
#endif // (SYS_PROJECT_FE != PROJECT_FE_ATSC)
#endif

#ifdef SUPPORT_FRANCE_HD
	nit_monitor_off();
#endif // SUPPORT_FRANCE_HD
#else
#ifdef AUTO_OTA
	ota_monitor_off();
#endif
	if (es->sim_onoff_enable)
		cc_sim_stop_monitor(es);
#ifndef CI_PLUS_PVR_SUPPORT
#if defined(CONAX_NEW_PUB) || (defined(_MHEG5_V20_ENABLE_) && !defined(NEW_DEMO_FRAME))
	prog_pos = get_prog_pos(es->prog_id);
    	si_monitor_off(prog_pos);
#endif
//PVR defined NEW_DEMO_FRAME, call cc_sim_stop_monitor(),but CAS need si_monitor_off()
	#if(CAS_TYPE==CAS_CDCA3||CAS_TYPE == CAS_TF||CAS_TYPE == CAS_CDCA||CAS_TYPE==CAS_GOS)
		prog_pos = get_prog_pos(es->prog_id);
	    si_monitor_off(prog_pos);
	#endif
#endif
#endif
#ifdef MULTI_CAS
#ifdef NEW_DEMO_FRAME
#ifdef COMBO_CA_PVR
	if((((dmx->type) & HLD_DEV_ID_MASK) == 0) && (ts_route_check_recording_by_nim_id(0) != RET_SUCCESS)) 
#endif
    {
        #ifndef MULTI_DESCRAMBLE
		#if (CAS_TYPE == CAS_ABEL)
		#else
    	api_mcas_stop_service(es->sim_id);
        #endif
        #endif
    }
#else
	api_mcas_stop_service();
#endif
    	if(frontend_change)
    	{
#if (defined(GET_CAT_BY_SIM)) && (defined(NEW_DEMO_FRAME))
			api_mcas_stop_transponder(es->sim_id);
#else
    		#ifdef MULTI_DESCRAMBLE
            if(api_mcas_get_prog_record_flag(es->prog_id) == FALSE)   //if the program is recording,don't stop descramble service
                api_mcas_stop_transponder_multi_des(ts_route->dmx_id-1);
            #else
			#if (CAS_TYPE == CAS_ABEL)
			#else
    		api_mcas_stop_transponder();
			#endif
#endif
			mcas_xpond_stoped = TRUE;
    	}
#endif
#endif

#if defined(SUPPORT_VMX_STD) && !defined(VMX_NEW_CC) //CAS_CM_ENABLE
	//libc_printf("cc_pre_play_channel: api_mcas_stop_service\n");
	api_mcas_stop_service();
    	if(frontend_change)
    	{
		//libc_printf("cc_pre_play_channel: api_mcas_stop_transponder\n");
    		api_mcas_stop_transponder();
    	}
#elif defined(SUPPORT_VMX) || defined(VMX_NEW_CC)
    	if(frontend_change)
    	{
			UINT8 dmx_id = 0;

			#ifdef VMX_PVR_SUPPORT
			libc_printf("cc_pre_play_channel: api_mcas_stop_transponder(g_pre_nim_id = %d)\n", g_pre_nim_id);
			dmx_id = g_pre_nim_id;
			#endif
    		api_mcas_stop_transponder_multi_des(dmx_id);
    	}
#endif

    	//NVOD
    	CC_PRINTF("CC Pre Play Channel 4 --- NVOD Save\n");
    	if((es->service_type==SERVICE_TYPE_NVOD_TS)&&(frontend_change))
    	{
    		get_tp_by_id(es->tp_id, &tp);
    		nvod_saveorload_tp_eit(0, &tp);
    	}

	//CI, avoid not descramble issue when cc frequently
	CC_PRINTF("CC Pre Play Channel 5 --- Stop CI\n");

#ifdef CI_PLUS_SUPPORT
	ci_stop_sdt_filter();
#endif

#if ((!defined CI_ALLPASS_ENABLE))
	if (ts_route->ci_enable)
#endif
	{
		service.monitor_id = es->sim_id;
#ifdef CI_SUPPORT
#ifdef  CI_ALLPASS_ENABLE
		api_ci_stop_service(NULL, &service, 0x03);
#else
		api_ci_stop_service(NULL, &service, ts_route->ci_slot_mask);
#endif
#endif
	}
#ifdef NEW_DEMO_FRAME //Temp Solution For PIP PVR new SI Monitor
	if(!es->not_oprate_subt_ttx)
	{
#if (SUBTITLE_ON == 1)
		subt_unregister(es->sim_id);
#endif
#if (TTX_ON == 1)
		ttx_unregister(es->sim_id);
#endif
#if (ISDBT_CC == 1)
		isdbtcc_unregister(es->sim_id);
#endif
	}
#endif

	//EPG Off
	//recommend: after si_monitor, for it maybe spend much time
	CC_PRINTF("CC Pre Play Channel 2 --- EPG Off\n");
//reduce the space for ota
#ifndef _BUILD_OTA_E_
	epg_off();
#endif

#ifdef CI_SUPPORT
	api_ci_mutex_lock();
#endif
	CC_PRINTF("CC Pre Play Channel 6 --- Leave Pre Play Channel\n");
}

/* Process After Play Channel */
static void cc_post_play_channel(struct nim_device *nim, struct dmx_device *dmx,
	struct ft_ts_route *ts_route, struct cc_es_info *es, UINT8 frontend_change)
{	
	T_NODE tp;
	P_NODE pnode;
	enum ci_protect_mode prot_mode;

#ifdef PUB_PORTING_PUB29
	if(NULL != post_play_callback && es)
	{
		post_play_callback(es->prog_id);
	}
#endif

#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
	UINT32 ciplus_tmp_tick = osal_get_tick();
	libc_printf("# Current @%s\n",__FUNCTION__);
	libc_printf("#\t tic = %d, tic used = %d, gap = %d\n", ciplus_tmp_tick, ciplus_tmp_tick-ciplus_cc_begin_tick, ciplus_tmp_tick-ciplus_cc_prev_tick);
	ciplus_cc_prev_tick = ciplus_tmp_tick;
#endif
     	//Start CA
     	CC_PRINTF("CC Post Play Channel 1 --- Start CA\n");


    	//EPG On
    	CC_PRINTF("CC Post Play Channel 2 --- EPG On\n");
//reduce the space for ota
#ifndef _BUILD_OTA_E_     
	if (epg_get_status()==STATUS_ON)
		epg_off(); // off epg before epg_on, to ensure open epg on correct service.
#ifdef _INVW_JUICE   
		epg_on_by_inview(dmx, es->sat_id, es->tp_id, es->service_id, 0);
#else
        if(FALSE == is_multiview_play)
        {
    		epg_on_ext(dmx, es->sat_id, es->tp_id, es->service_id);
        }
#endif // _INVW_JUICE
#endif // _BUILD_OTA_E_
    
    	//SI Monitor On
    	CC_PRINTF("CC Post Play Channel 3 --- SI Monitor On\n");

   	//NVOD
   	CC_PRINTF("CC Post Play Channel 4 --- NVOD Load\n");
    	if((es->service_type==SERVICE_TYPE_NVOD_TS)&&(frontend_change))
    	{
        	get_tp_by_id(es->tp_id, &tp);
        	nvod_saveorload_tp_eit(1, &tp);
    	}    

	//CI
	CC_PRINTF("CC Post Play Channel 5 --- Start CI\n");
	
	get_prog_by_id(es->prog_id, &pnode);
	//free prog ts bypass ci slot
	if(!pnode.ca_mode)
	{
#if ((defined(CI_SUPPORT)) && (!defined(CI_PLUS_SUPPORT))&&(!defined CI_ALLPASS_ENABLE))
		api_set_nim_ts_type(2, ts_route->ci_slot_mask);
#endif
	}
	//CI, avoid not descramble issue when cc frequently
#ifdef CI_SUPPORT
	api_ci_mutex_unlock();
#endif

#if ((defined CI_ALLPASS_ENABLE))
	if (1)
#else
#ifdef CI_PLUS_SUPPORT
    if (ts_route->ci_enable) //We need pass CAM for ALL time when CI PLUS enable
	                         //So we just bypass the CAM when do auto scan
#else	//CI
	if (ts_route->ci_enable && (pnode.ca_mode))
#endif
#endif
	{
		CC_PRINTF("\nCI Start\n");

		ci_dev_list.nim_dev = nim;
		ci_dev_list.dmx_dev = dmx;
		ci_service.prog_id = es->prog_id;
		ci_service.video_pid = es->v_pid;
		ci_service.audio_pid = es->a_pid;
		ci_service.ttx_pid = es->ttx_pid;
		ci_service.subt_pid = es->subt_pid;
		ci_service.monitor_id = es->sim_id;

#if (!defined(CC_USE_TSG_PLAYER) && defined(CI_SUPPORT))

#if ((defined CI_ALLPASS_ENABLE))
		api_ci_start_service(&ci_dev_list, &ci_service, 0x03);
#else

#ifdef CI_PLUS_SUPPORT
		CI_SHUNNING_DEBUG("# check pnode @%s\n", __FUNCTION__);
		CI_SHUNNING_DEBUG("#       pnode.prog_number = %d\n", pnode.prog_number);
		CI_SHUNNING_DEBUG("#       pnode.shunning_protected = %d\n", pnode.shunning_protected);
		if (pnode.shunning_protected == 1)
			prot_mode = ci_service_shunning(pnode.tp_id, pnode.prog_number);
		else
			prot_mode = CI_PROTECTED_IN_ACTIVE;

		if(prot_mode == CI_PROTECTED_IN_ACTIVE)
		{
			api_ci_start_service(&ci_dev_list, &ci_service, ts_route->ci_slot_mask);
		}
		else
		{
			api_ci_stop_service(NULL, &ci_service, ts_route->ci_slot_mask);
			api_set_nim_ts_type(2, ts_route->ci_slot_mask);
		}
#else //CI
		api_ci_start_service(&ci_dev_list, &ci_service, ts_route->ci_slot_mask);
#endif
#endif

#endif
	}
	else
	{
		CC_PRINTF("\nCI Not Start\n");
	}
#ifdef CI_PLUS_SERVICESHUNNING
	ci_start_sdt_filter(es->tp_id);
#endif

#ifdef NEW_DEMO_FRAME //Temp Solution For PIP PVR new SI Monitor
	if(!es->not_oprate_subt_ttx)
	{
#if	(SUBTITLE_ON == 1)
		subt_register(es->sim_id);
#endif
#if	(TTX_ON == 1)
		ttx_register(es->sim_id);
#endif

#if	(ISDBT_CC == 1)
		isdbtcc_register(es->sim_id);
#endif
	}
#endif

#if (defined(_MHEG5_V20_ENABLE_) )
	UINT16 prog_pos = 0xffff;		

	prog_pos = get_prog_pos(es->prog_id);
	MHEG5_ReceiverStartApplications((prog_pos>0xFFF0)?(UINT32)si_get_cur_channel():prog_pos);
#endif

	CC_PRINTF("CC Post Play Channel 6 --- Leave Post Play Channel\n");
}    

static void PrintTSRoute(UINT8 dmxID)
{
	//libc_printf("============ ts route ===========\n",__FUNCTION__);
	UINT8 ts_id, tsi_id, ci_mode;
	int dmx_id = TSI_DMX_0;
	tsi_check_dmx_src(dmx_id, &ts_id, &tsi_id, &ci_mode);
	//libc_printf("route:TSI %d --> %d -->DMX %d (%d)   %s\n",
	//			tsi_id, ts_id, dmx_id-1, ci_mode,(dmx_id == dmxID ? "play":""));

	dmx_id = TSI_DMX_1;
	tsi_check_dmx_src(dmx_id, &ts_id, &tsi_id, &ci_mode);
	//libc_printf("route:TSI %d --> %d -->DMX %d (%d)   %s\n",
	//			tsi_id, ts_id, dmx_id-1, ci_mode,(dmx_id == dmxID ? "play":""));

	return;
}

// @HM_CONAX3515
#if ((defined(CAS9_V6) && defined(MULTI_DESCRAMBLE)) || defined(CAS9_PVR_SCRAMBLED) || defined(VMX_PVR_SUPPORT))
UINT8 nim_change_flag = FALSE;
UINT8 get_nim_change_flag()
{
    return nim_change_flag;
}

#ifdef VMX_PVR_SUPPORT
void set_nim_change_flag(UINT8 flag, UINT8 pre_nim_id)
{
	//libc_printf("set_nim_change_flag(%d, %d)\n", flag, pre_nim_id);

	g_pre_nim_id = pre_nim_id;	
    nim_change_flag = flag;
}
#else
void set_nim_change_flag(UINT8 flag)
{
    nim_change_flag = flag;
}
#endif
#endif

/* Play Channel */
void cc_play_channel(UINT32 cmd, struct ft_frontend *ft, struct cc_param *param)
{
    UINT32 cmd_bits = cmd;
    UINT32 channel_pos;
    UINT32 hde_mode;
    struct cc_es_info *es = &param->es;
    struct cc_device_list *dev_list = &param->dev_list;
    UINT16 prog_pos = 0xffff;
    UINT16 video_pid = es->v_pid & 0x1fff;
    UINT16 audio_pid = es->a_pid & 0x1fff;
#if 1
    P_NODE temp_Node;
    get_prog_by_id(es->prog_id, &temp_Node);
 //   libc_printf("********* prog id : %d, TP ID : %d *********\n",temp_Node.prog_number,temp_Node.tp_id);
    PrintTSRoute(ft->ts_route.dmx_id);
#endif

#ifdef CHCHG_TICK_PRINTF
	cc_play_tick = osal_get_tick();
//	libc_printf("####CHCHG %s():line%d start play channel, tick =%d\n", __FUNCTION__,__LINE__, cc_play_tick);
#endif

#ifdef CI_PLUS_CHANGE_CHANNEL_TIME_DEBUG
	ciplus_cc_begin_tick = osal_get_tick();
//	libc_printf("# CI Plus Test Change channel time begin (@%s)\n", __FUNCTION__);
//	libc_printf("#\t begin tick = %d\n", ciplus_cc_begin_tick);
	ciplus_cc_prev_tick = ciplus_cc_begin_tick;
#endif
	CC_PRINTF("CC Play Channel 1 --- Set Cmd Bits\n");

	osal_task_dispatch_off();
	cc_cmd_cnt = 0;
	osal_task_dispatch_on();

    //Check Hde Mode
    hde_mode = hde_get_mode();
#if defined(HDTV_SUPPORT) && !defined(CHANCHG_VIDEOTYPE_SUPPORT)
    if(hde_mode == VIEW_MODE_MULTI)
    {
   	    cmd_bits &= ~CC_CMD_CLOSE_VPO;
    }
    if (cmd_bits & CC_CMD_CLOSE_VPO)
        enable_fill_blk_screen(FALSE); // fill black screen is slow
    else
        enable_fill_blk_screen(TRUE);
#else
	if(/*(hde_mode == VIEW_MODE_PREVIEW) ||*/ (hde_mode == VIEW_MODE_MULTI))
	{
   	    cmd_bits &= ~CC_CMD_CLOSE_VPO;
	}
#endif

	if(es->blk_enable)
		cmd_bits |= CC_CMD_FILL_FB;
		
    	//Check Video ES
#if (defined(_MHEG5_ENABLE_) || defined(_MHEG5_V20_ENABLE_) )
	cmd_bits |= CC_CMD_STOP_VIDEO;
  	if((es->service_type) &&(video_pid != 0)&&(video_pid != INVALID_PID))
		cmd_bits |= CC_CMD_START_VIDEO;
	else
	{
		cmd_bits |= CC_CMD_STOP_VIDEO;
		//if(hde_get_mode() != VIEW_MODE_MULTI)
		//	cmd_bits |= CC_CMD_STOP_VIDEO_VPO;
	}
#else
    cmd_bits |= CC_CMD_STOP_VIDEO;
    if(video_pid != 0 && video_pid != INVALID_PID)
    {
        cmd_bits |= CC_CMD_START_VIDEO;
#ifdef CHANNEL_CHANGE_VIDEO_FAST_SHOW
	    cmd_bits |= CC_CMD_INFO_VPO_CHANCHNG;
#endif
 	    //Check Video ES Type
    	if(es->v_type)
    	{

    	}
    }
    else
    {
	    P_NODE p_node;
	    if(SUCCESS==get_prog_by_id(es->prog_id, &p_node))
	    {
            if(p_node.av_flag)
                cmd_bits |= CC_CMD_STOP_VIDEO;
	    }
    }
#endif
		
    	//Check Audio ES
#if (defined(_MHEG5_ENABLE_) || defined(_MHEG5_V20_ENABLE_) )
	cmd_bits |= CC_CMD_STOP_AUDIO;
	if(audio_pid != 0 && audio_pid != INVALID_PID)
		cmd_bits |= CC_CMD_START_AUDIO;

	if((video_pid == 0 || video_pid == 8191) && audio_pid != 0 && audio_pid < 8190)
    {
      	cmd_bits &= ~(CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);
    }
    if( ( video_pid == 0 || video_pid == 8191 ) && (audio_pid == 0 || audio_pid == 8191)) 
    {
      	cmd_bits &= ~(CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);        
    }
#else
    cmd_bits |= CC_CMD_STOP_AUDIO;
    if(audio_pid != 0 && audio_pid != INVALID_PID)
        cmd_bits |= CC_CMD_START_AUDIO;
    //If Radio Channel, don't Close Vpo or Fill Video Frame Buffer
    if((video_pid == 0 || video_pid == 8191) && audio_pid != 0 && audio_pid < 8190)
    {
        cmd_bits &= ~(CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);
    }
#endif

    	cmd_bits |= CC_CMD_STOP_DMX|CC_CMD_START_DMX;

		cmd_bits |= CC_CMD_START_SI_MONITOR;
		
		cmd_bits |= CC_CMD_STOP_MCAS_SERVICE;
		
    	UINT8 antenna_change = 0;
    	UINT8 xpond_change = 0;
    	struct nim_config config;

    	if(ft->nim != NULL)
    	{
    		//Judge whether antenna and transponder need change or not
        	dev_get_nim_config(ft->nim, ft->xpond.common.type, &config);
        	if(ft->antenna.antenna_enable == 1)
        	{
            		if((ft->xpond.s_info.pol != config.xpond.s_info.pol) 
				||(MEMCMP(&ft->antenna, &config.antenna, sizeof(struct ft_antenna))))
                		antenna_change = 1;
        	}
        	if (MEMCMP(&ft->xpond, &config.xpond, sizeof(union ft_xpond)))
        	{  
                xpond_change = 1; 
                if(LNB_CTRL_UNICABLE == ft->antenna.lnb_type) 
                   antenna_change = 1;   //need send channel change command to UNICABLE LNB 
        	}
    		else if(TRUE == frontend_check_nim_param(ft->nim, &ft->xpond, &ft->antenna))
    		{
    			xpond_change = 1;
    		}
#if (defined(PUB_PORTING_PUB29)) && ((SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC)) )
		play_xpond_info.frq = ft->xpond.t_info.frq;
		play_xpond_info.sym = ft->xpond.t_info.sym;	
		play_xpond_info.pol = 0;
		play_xpond_info.guard_interval = ft->xpond.t_info.guard_intl;
		play_xpond_info.FFT = ft->xpond.t_info.fft_mode;
		play_xpond_info.modulation = ft->xpond.t_info.modulation;
		play_xpond_info.bandwidth = ft->xpond.t_info.band_width/1000;
		play_xpond_info.inverse = ft->xpond.t_info.inverse;
#endif
			 // @HM_CONAX3515
            #if ((defined(CAS9_V6) && defined(MULTI_DESCRAMBLE)) || defined(CAS9_PVR_SCRAMBLED) || defined(VMX_PVR_SUPPORT))
            if(TRUE == get_nim_change_flag())
            {
                antenna_change = 1;       //change tuner
            }
            #endif
    	}

		//Process Before Play Channel
    	CC_PRINTF("CC Play Channel 2 --- Pre Play Channel\n");
    	cc_pre_play_channel(param->dev_list.dmx, es, &ft->ts_route, (antenna_change|xpond_change));


		//Set Antenna, Transponder
    	CC_PRINTF("CC Play Channel 3 --- Set Frontend\n");
    	CC_PRINTF("%s(): before set frontend, tick=%d\n",__FUNCTION__,osal_get_tick());
		if(ft->nim != NULL)
		{
		//Change Antenna and Transponder	
        	if(antenna_change == 1)
        	{
				//do it in driver act, for: set front after dmx&dec closed
        		//frontend_set_antenna(ft->nim, &ft->antenna, &ft->xpond, 1);
        		cmd_bits |= CC_CMD_SET_ANTENNA;
        	}
              if(xpond_change == 1)
        	{
        		/*frontend_set_nim(ft->nim, &ft->antenna, &ft->xpond, 1);
        		//After Set Front End, Enable TDT Parse, not to do under S
        		if(ft->xpond.s_info.type != FRONTEND_TYPE_S)
        		{
        			enable_time_parse();
        		}*/
        		cmd_bits |= CC_CMD_SET_XPOND;
        	}     
    	}    	
    	
#ifdef SFU_TEST_SUPPORT
	cmd_bits |= CC_CMD_SET_XPOND;
#endif   	

#ifndef PUB_PORTING_PUB29
    	//Set TS Route
    	CC_PRINTF("CC Play Channel 4 --- Set TS Route\n");
#ifndef PVR_DMX_DELAY_SUPPORT_USE_DMX2
    	frontend_set_ts_route(ft->nim, &ft->ts_route);
#endif
    	CC_PRINTF("%s(): before call cc_driver_act, tick=%d\n", __FUNCTION__, osal_get_tick());
#endif

	//Play Channel
	CC_PRINTF("CC Play Channel 5 --- Driver Act\n");
    cc_driver_act(cmd_bits, es, dev_list, ft);
    CC_PRINTF("%s(): after call cc_driver_act, tick=%d\n", __FUNCTION__, osal_get_tick());
#ifdef CC_POST_CALLBACK
	if(param->callback!=NULL)
		param->callback();
#endif
#ifdef CHCHG_TICK_PRINTF
	cc_play_tick = 0;
#endif
	//Process After Play Channel
	CC_PRINTF("CC Play Channel 6 --- Post Play Channel\n");
    cc_post_play_channel(ft->nim, param->dev_list.dmx, &ft->ts_route, es, (antenna_change|xpond_change));
    CC_PRINTF("%s(): after post_play_channel, tick=%d\n", __FUNCTION__, osal_get_tick());
	CC_PRINTF("CC Play Channel 7 --- Leave Play Channel\n");

#ifdef PUB_PORTING_PUB29
	l_cc_crnt_state = (es->v_pid==0||es->v_pid==8191)? CC_STATE_PLAY_RADIO:CC_STATE_PLAY_TV;
#endif
	
#ifdef CI_PLUS_TEST_CASE
	//CI PLUS TEST CASE
	api_ciplus_testcase(CIPlus_case_idx);
	CIPlus_case_idx = 0xff;
#endif

#if (SYS_PROJECT_FE == PROJECT_FE_DVBC)
#ifndef NEW_DEMO_FRAME
#ifdef SUBTITLE_ON
	prog_pos = get_prog_pos(es->prog_id);
	si_monitor_on(prog_pos);
#endif
#endif
#endif

}

/* Process Before Stop Channel */
void cc_pre_stop_channel(struct dmx_device *dmx,struct cc_es_info *es,UINT8 frontend_change)
{
    	UINT16 prog_pos = 0xffff;
    	T_NODE tp;

     	//Stop CA
     	CC_PRINTF("CC Pre Stop Channel 1 --- Stop CA\n");
#ifdef MULTI_CAS
#ifdef NEW_DEMO_FRAME
#ifdef COMBO_CA_PVR
	if((((dmx->type) & HLD_DEV_ID_MASK) == 0) && (ts_route_check_recording_by_nim_id(0) != RET_SUCCESS)) 
#endif
{
	#if defined(MULTI_DESCRAMBLE)
		#if !(defined(CAS9_V6) && defined(CAS9_PVR_SID)) // @HM_CONAX3515
        if(api_mcas_get_prog_record_flag(es->prog_id) == FALSE)   //if the program is recording,don't stop descramble service
        #endif
        {
            api_mcas_stop_service_multi_des(es->prog_id,es->sim_id);
        }
    #else
    		#if (CAS_TYPE == CAS_ABEL)
			api_mcas_stop_service();
		#else
    	api_mcas_stop_service(es->sim_id);
    #endif
    	#endif
}
#else
		api_mcas_stop_service();
#endif
    	if(frontend_change)
    	{
#if (defined(GET_CAT_BY_SIM)) && (defined(NEW_DEMO_FRAME))
			api_mcas_stop_transponder(es->sim_id);
#else
		#ifdef MULTI_DESCRAMBLE
            UINT8 index = (dmx->type)&HLD_DEV_ID_MASK;
            //libc_printf("%s dmx_index=%d\n",__FUNCTION__,index);
            if(api_mcas_get_prog_record_flag(es->prog_id) == FALSE)   //if the program is recording,don't stop descramble service
                api_mcas_stop_transponder_multi_des(index);
        #else
    		api_mcas_stop_transponder();
			#ifdef SUPPORT_CAS_A
			sie_stop_emm_service();
			#endif
		#endif
#endif
			mcas_xpond_stoped = TRUE;
    	}
#endif

#if defined(SUPPORT_VMX_STD) && !defined(VMX_NEW_CC) //CAS_CM_ENABLE
	//libc_printf("cc_pre_stop_channel: api_mcas_stop_service\n");
	api_mcas_stop_service();
    	if(frontend_change)
    	{
		//libc_printf("cc_pre_stop_channel: api_mcas_stop_transponder\n");
    		api_mcas_stop_transponder();
    	}
#elif defined(SUPPORT_VMX) || defined(VMX_NEW_CC)
		#ifdef VMX_PVR_SUPPORT
		if( FALSE == api_mcas_get_prog_record_flag(es->service_id) )
		#endif
		{
		    //libc_printf("cc_pre_stop_channel: api_mcas_stop_service_multi_des(0x%X)\n", es->service_id);
		    vmx_StopDescrambling(es->service_id);
		    api_mcas_stop_service_multi_des(es->service_id);
		    if(frontend_change)
		    {
		    	#ifdef VMX_PVR_SUPPORT
			    UINT8 dmx_id = g_pre_nim_id;
				#else
				UINT8 dmx_id = ((dmx->type)&HLD_DEV_ID_MASK) - 1;
				#endif
				
			    //libc_printf("cc_pre_stop_channel: api_mcas_stop_transponder\n");
			    api_mcas_stop_transponder_multi_des(dmx_id);
		    }
		}
#endif

    	//SI Monitor Off
    	CC_PRINTF("CC Pre Stop Channel 3 --- SI Monitor Off\n");    	
#ifndef NEW_DEMO_FRAME //temp solution for pip pvr new si monitor
	prog_pos = get_prog_pos(es->prog_id);
    	si_monitor_off(prog_pos);
#else
	if (es->sim_onoff_enable)
		cc_sim_stop_monitor(es);
#if defined(CONAX_NEW_PUB) || (defined(_MHEG5_V20_ENABLE_) && !defined(NEW_DEMO_FRAME))
    	prog_pos = get_prog_pos(es->prog_id);
    	si_monitor_off(prog_pos);
#endif
//PVR defined NEW_DEMO_FRAME, call cc_sim_stop_monitor(),but CAS need si_monitor_off()
	#if(CAS_TYPE==CAS_CDCA3||CAS_TYPE == CAS_TF|CAS_TYPE == CAS_CDCA||CAS_TYPE==CAS_GOS)
		prog_pos = get_prog_pos(es->prog_id);
	    si_monitor_off(prog_pos);
	#endif

#endif

    	//NVOD
    	CC_PRINTF("CC Pre Stop Channel 4 --- NVOD Save\n");
    	if((es->service_type == SERVICE_TYPE_NVOD_TS) && (frontend_change))
    	{
    		get_tp_by_id(es->tp_id, &tp);
    		nvod_saveorload_tp_eit(0, &tp);
    	}    

	//EPG Off
	//recommend: after si_monitor, for it maybe spend much time
	CC_PRINTF("CC Pre Stop Channel 2 --- EPG Off\n");
//reduce the space for ota
#ifndef _BUILD_OTA_E_    
    	epg_off();
#endif

	CC_PRINTF("CC Pre Stop Channel 5 --- Leave Pre Stop Channel\n");
}

/* Stop Channel *
 * For Example, when enter main menu, this function will be called by upper layer */
void cc_stop_channel(UINT32 cmd, struct cc_es_info *es, struct cc_device_list *dev_list)
{
    	UINT32 cmd_bits = cmd;
    	UINT32 channel_pos;
    	UINT32 hde_mode;

#if (defined(_MHEG5_V20_ENABLE_) )
	MHEG5_ReceiverStopApplications();
#endif

	CC_PRINTF("CC Stop Channel 1 --- Set Cmd Bits\n");
    	//Check Hde Mode to Determine Whether Close Vpo
    	hde_mode = hde_get_mode();

#if defined(HDTV_SUPPORT) && !defined(CHANCHG_VIDEOTYPE_SUPPORT)
        if(hde_mode == VIEW_MODE_MULTI)
        {
       	    cmd_bits &= ~CC_CMD_CLOSE_VPO;
        }
        if (cmd_bits & CC_CMD_CLOSE_VPO)
            enable_fill_blk_screen(FALSE); // fill black screen is slow
        else
            enable_fill_blk_screen(TRUE);
#else
    	if(/*(hde_mode == VIEW_MODE_PREVIEW) || */(hde_mode == VIEW_MODE_MULTI))
    	{
    		cmd_bits &= ~CC_CMD_CLOSE_VPO;
    	}
#endif

	// For Invalid-Program, Audio and Video PID are both 0
	if((es->v_pid == 0) && (es->a_pid == 0))
	{
		cmd_bits |= (CC_CMD_STOP_VIDEO | CC_CMD_STOP_AUDIO);
	}
       
    	//Check Video ES
    	if(es->v_pid != 0)
    	{
    		cmd_bits |= CC_CMD_STOP_VIDEO;
    	}
    
    	//Check Audio ES
    	if(es->a_pid != 0)
    	{
        	cmd_bits |= CC_CMD_STOP_AUDIO;
        	//If Radio Channel, don't Close Vpo or Fill Video Frame Buffer
        	if(es->v_pid == 0)
        	{
            		cmd_bits &= ~(CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);
        	}
    	}
	#if !(defined(SUPPORT_HW_CONAX)|defined(MULTI_CAS))
	#if defined(SUPPORT_VMX_STD) || defined(SUPPORT_VMX)
    	cmd_bits |= CC_CMD_STOP_DMX;

    	//Process Before Stop Channel
    	CC_PRINTF("CC Stop Channel 2 --- Pre Stop Channel\n");
    	cc_pre_stop_channel(dev_list->dmx, es, 0);
	#else
		cmd_bits |= CC_CMD_STOP_DMX;
		CC_PRINTF("CC Stop Channel 2 --- Pre Stop Channel\n");
		cc_pre_stop_channel(dev_list->dmx, es, 1);
	#endif
	#else //hwca && swca
		cmd_bits |= CC_CMD_DMX_DISABLE;
		cc_pre_stop_channel(dev_list->dmx, es, 0);
	#endif
	//Stop Channel
	CC_PRINTF("CC Stop Channel 3 --- Driver Act\n");
    	cc_driver_act(cmd_bits, es, dev_list, NULL);
	CC_PRINTF("CC Stop Channel 4 --- Leave Stop Channel\n");

#ifdef PUB_PORTING_PUB29
	l_cc_crnt_state = CC_STATE_STOP;
#endif
}

/* Show Background Logo */
static void cc_show_logo(UINT32 cmd, struct cc_logo_info *plogo, struct cc_device_list *dev_list)
{
    	struct cc_es_info es;
    	INT32 ret;
    	UINT8 i,j;
    	UINT32 cmd_bits;

        struct VDec_StatusInfo decv_status;
        if(dev_list->dmx==NULL)
        {
            vdec_io_control(dev_list->vdec, VDEC_IO_GET_STATUS, (UINT32)(&decv_status));
            if(decv_status.uCurStatus == VDEC27_STARTED)
                return;
        }

		CC_PRINTF("CC Show Logo 1 --- Driver Act\n");
		if(sys_ic_get_chip_id() != ALI_S3281)
        	vdec_start(dev_list->vdec);//fix pause issue
        	
    	MEMSET(&es, 0, sizeof(es));
    	cmd_bits = cmd | CC_CMD_STOP_VIDEO | CC_CMD_STOP_DMX |CC_CMD_STOP_AUDIO;
    	cc_driver_act(cmd_bits, &es, dev_list, NULL);

	CC_PRINTF("CC Show Logo 2 --- Show Logo\n");
    	if((plogo != NULL) && (plogo->addr != NULL) && (plogo->size > 0) && (plogo->sto != NULL))
    	{
       	struct vdec_io_reg_callback_para tpara;
        	void* pWriteBuffer;
        	UINT32 uSizeGot;
#ifdef DUAL_ENABLE
            UINT8 *logo_buf;
            logo_buf = (UINT8 *)MALLOC(plogo->size);
#endif

        	reset_vdec_first_show();
        	tpara.eCBType = VDEC_CB_FIRST_SHOWED;
        	tpara.pCB = cb_vdec_first_show;
        	vdec_io_control(dev_list->vdec, VDEC_IO_REG_CALLBACK, (UINT32)(&tpara));
            vdec_io_control(dev_list->vdec, VDEC_SET_DMA_CHANNEL, DMA_INVALID_CHA); //for Show logo //memcpy,must be set dma invalid
        	ret = vdec_start(dev_list->vdec);
#ifdef ADJUST_SPECIAL_LOGO_QUALITY
		struct vpo_device *vpo_dev = (struct vpo_device*)dev_get_by_id(HLD_DEV_TYPE_DIS, 0);
		vpo_ioctl(vpo_dev, VPO_IO_CHANGE_YC_INIT_PHASE, 1);
#endif
        	for(i = 0;i < 2; i++)
        	{
			ret = vdec_vbv_request((void *)dev_list->vdec, plogo->size, &pWriteBuffer, &uSizeGot,
				(struct control_block *)NULL);
#ifndef HDTV_SUPPORT
#ifdef DUAL_ENABLE            
			if(((UINT32)plogo->addr&0x80000000) ||((UINT32)plogo->addr&0xA0000000))
			{
				MEMCPY(pWriteBuffer, plogo->addr,uSizeGot);
			}
			else
			{
            	    sto_get_data(plogo->sto, (UINT8 *)logo_buf, plogo->addr, uSizeGot);
                    MEMCPY(pWriteBuffer,logo_buf,uSizeGot);
			}
#else
			sto_get_data(plogo->sto, (UINT8 *)pWriteBuffer, plogo->addr, uSizeGot);
#endif
#else
			if (i == 0)
			{
#ifdef DUAL_ENABLE            
            	    sto_get_data(plogo->sto, (UINT8 *)logo_buf, plogo->addr, uSizeGot);
                    MEMCPY(pWriteBuffer,logo_buf,uSizeGot);
#else
		    		sto_get_data(plogo->sto, (UINT8 *)pWriteBuffer, plogo->addr, uSizeGot);
#endif
			}
			else if (uSizeGot >= 32)
			{
#ifdef DUAL_ENABLE  
                MEMSET(logo_buf, 0, 32);
                MEMCPY(pWriteBuffer,logo_buf,32);
#else
				MEMSET(pWriteBuffer, 0, 32);
#endif
				uSizeGot = 32;
			}
#endif
			vdec_vbv_update((void *)dev_list->vdec, uSizeGot);
        	}
	
        	osal_task_sleep(10);
			j = 0;
        	while(!ck_vdec_first_show() && j<100)
        	{
        		osal_task_sleep(10);
				j++;
        	}
#ifdef DUAL_ENABLE            
            FREE(logo_buf);
#endif
        	ret = vdec_stop(dev_list->vdec, FALSE, FALSE);
#ifdef ADJUST_SPECIAL_LOGO_QUALITY
		vpo_ioctl(vpo_dev, VPO_IO_CHANGE_YC_INIT_PHASE, 0);
#endif

    	}

#ifdef PUB_PORTING_PUB29
	l_cc_crnt_state = CC_STATE_STOP;
#endif
	CC_PRINTF("CC Show Logo 3 --- Leave Show Logo\n");
}

#if (defined(PUB_PORTING_PUB29)) && ((SYS_PROJECT_FE == PROJECT_FE_ATSC)||( SYS_PROJECT_FE == PROJECT_FE_DVBT ))
BOOL cc_lock_program(UINT32 cur_channel)
{
	BOOL ret_bool = TRUE;
	P_NODE p_node;
	struct ft_frontend ft;
	struct cc_param param;
	BOOL ci_start_service = FALSE;
	UINT32 cmd_bits = 0;
	struct nim_config config;

	MonitorRst();//clear dm counter

	if(get_prog_by_id(cur_channel, &p_node) != SUCCESS)
		return FALSE;

	l_cc_crnt_state = (p_node.av_flag)? CC_STATE_PLAY_TV:CC_STATE_PLAY_RADIO;
	#ifdef HDTV_SUPPORT
	cmd_bits = CC_CMD_CLOSE_VPO|CC_CMD_STOP_AUDIO;
	#else
	cmd_bits = CC_CMD_CLOSE_VPO|CC_CMD_STOP_AUDIO|CC_CMD_FULL_FB;
	#endif

	if( prt_pre_play_channel(&p_node, &ft, &param, &ci_start_service, FALSE) == FALSE )
		return FALSE;
		
	
	if(ft.nim != NULL)
	{
		dev_get_nim_config(ft.nim, ft.xpond.common.type, &config);
		if(MEMCMP(&ft.xpond, &config.xpond, sizeof(union ft_xpond)))
			cmd_bits |= CC_CMD_SET_XPOND;
	}
	
#if(SYS_PROJECT_FE == PROJECT_FE_ATSC)
//libc_printf("cur_channel[%x]\n",cur_channel);
	UINT16 p_idx= get_prog_pos(cur_channel);
//libc_printf("p_idx[%x]\n",p_idx);	

	if (pre_tp_id != l_cc_cmd.pids.tp_id)
		psip_monitor_stop();
	else
		psip_pmt_monitor_off(p_idx);
#endif	

	struct MPSource_CallBack MPCallBack;
	struct PIPSource_CallBack PIPCallBack;
	struct VDecPIPInfo tInitInfo;
#if(SYS_PROJECT_FE == PROJECT_FE_ATSC)
	;//vdec_set_output((struct vdec_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DECV), SW_PASS_MODE, &tInitInfo, &MPCallBack, &PIPCallBack);
#elif (SYS_PROJECT_FE == PROJECT_FE_DVBT)
	;//vdec_set_output(/*(struct vdec_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DECV)*/get_selected_decoder(), SW_PASS_MODE, &tInitInfo, &MPCallBack, &PIPCallBack);
#endif

#if(SYS_PROJECT_FE == PROJECT_FE_ATSC)
	if(get_vct_changing_flag() == FALSE)
#endif
	cc_driver_act(cmd_bits, &(param.es), &(param.dev_list), &ft);
#if(SYS_PROJECT_FE == PROJECT_FE_ATSC)
		pre_tp_id = l_cc_cmd.pids.tp_id;
		psip_monitor_start((UINT32)pre_tp_id, p_idx);
#endif


	return ret_bool;
}
#endif

/* Implement CC Command */
static void cc_cmd_implement(struct libpub_cmd *cmd)
{
    	UINT32 cmd_finish_bit = 0;
    	struct ft_frontend *ft = NULL;
    	struct ft_ts_route *ts_route = NULL;
    	struct cc_es_info *es = NULL;
    	struct cc_device_list *dev_list = NULL;
    	struct cc_logo_info* plogo = NULL;
    	struct cc_param *param = NULL;
#if (defined(PUB_PORTING_PUB29)) && ((SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC)) )
		UINT16 band_width = 0;
#endif

    	switch(cmd->cmd_type)
    	{
	case LIBPUB_CMD_CC_PLAY:
        	ft = (struct ft_frontend*)cmd->data1;
        	param = (struct cc_param*)cmd->data2;
        	//Show Black Screen
        	if(cmd->para1 == 1)
        	{
            		cmd->cmd_bit |= (CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);
        	}
       
        	CC_PRINTF("%s(): call cc_play_channel(),tick=%d\n", __FUNCTION__, osal_get_tick());     
        	cc_play_channel(cmd->cmd_bit, ft, param);
        	cmd_finish_bit = LIBPUB_FLG_CC_PLAY_BIT;
        	break;
    	case LIBPUB_CMD_CC_STOP:
        	es = (struct cc_es_info *)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
        	//Show Black Screen
        	if(cmd->para1 == 1)
        	{
            		cmd->cmd_bit |= (CC_CMD_CLOSE_VPO|CC_CMD_FILL_FB);
        	}
   
        	cc_stop_channel(cmd->cmd_bit, es, dev_list);
        	cmd_finish_bit = LIBPUB_FLG_CC_STOP_BIT;
    		break;
    	case LIBPUB_CMD_CC_PAUSE_VIDEO:
        	es = (struct cc_es_info *)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
		cc_pause_video(cmd->cmd_bit, es, dev_list);
        	cmd_finish_bit = LIBPUB_FLG_CC_PAUSE_BIT;
    		break;
    	case LIBPUB_CMD_CC_RESUME_VIDEO:
        	es = (struct cc_es_info *)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
		cc_resume_video(cmd->cmd_bit,es, dev_list);
        	cmd_finish_bit = LIBPUB_FLG_CC_PAUSE_BIT;
    		break;
    	case LIBPUB_CMD_CC_SWITCH_APID:
        	es = (struct cc_es_info *)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
		cc_switch_apid(cmd->cmd_bit, es, dev_list);
        	cmd_finish_bit = LIBPUB_FLG_CC_SWITCH_APID_BIT;
    		break;
    	case LIBPUB_CMD_CC_SWITCH_ACH:
        	es = (struct cc_es_info *)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
        	cmd->cmd_bit = CC_CMD_AUDIO_SWITCH_CHAN;
        	cc_driver_act(cmd->cmd_bit, es, dev_list, NULL);
        	cmd_finish_bit = LIBPUB_FLG_CC_SWITCH_ACH_BIT;
    		break;
    	case LIBPUB_CMD_CC_SHOW_LOGO:
        	plogo = (struct cc_logo_info*)cmd->data1;
        	dev_list = (struct cc_device_list *)cmd->data2;
		cc_show_logo(cmd->cmd_bit, plogo, dev_list);
        	cmd_finish_bit = LIBPUB_FLG_CC_LOGO_BIT;
    		break;
#ifdef CC_USE_TSG_PLAYER
    	case LIBPUB_CMD_CC_START_PATCH:
			cc_start_patch(cmd->para1);
        	cmd_finish_bit = LIBPUB_FLG_CC_PATCH_BIT;
    		break;
#endif
	case LIBPUB_CMD_CC_AERIAL_CHG_CH:
			//band_width = (UINT16)cmd->para2;
		#ifndef PUB_PORTING_PUB29
			cc_aerial_signal_monitor((struct ft_frontend*)cmd->para1);//(cmd->para1, band_width);
			#endif
			break;
#if (defined(PUB_PORTING_PUB29)) && ((SYS_PROJECT_FE == PROJECT_FE_ATSC)||( SYS_PROJECT_FE == PROJECT_FE_DVBT ))
		case LIBPUB_CMD_CC_LOCK:
			cc_lock_program(cmd->para1);
			cmd_finish_bit = MID27_FLG_CC_LOCK_BIT;
			break;
#endif
    	}

	if(cmd->sync == 1)
	{
        	libpub_declare_cmd_finish(cmd_finish_bit);
	}
}


/********************************************************
*external APIs
/*******************************************************/
void chchg_init(void)
{
	BOOL ret_bool;
#ifdef CHCHG_TICK_PRINTF
	struct vdec_io_reg_callback_para tpara;
	struct vdec_device *v_dec = (struct vdec_device *)dev_get_by_id(HLD_DEV_TYPE_DECV, 0);
#endif
	
	l_cc_sema_id = osal_semaphore_create(1);
	if (OSAL_INVALID_ID == l_cc_sema_id)
	{
		CC_PRINTF("Create l_cc_sema_id failed!\n");
	}
		
	libpub_cmd_handler_register(LIBPUB_CMD_CC, cc_cmd_implement);
	
	ret_bool = libpub_overlay_cmd_register(LIBPUB_CMD_CC_PLAY);
	ASSERT(ret_bool);
	ret_bool = libpub_overlay_cmd_register(LIBPUB_CMD_CC_STOP);
	ASSERT(ret_bool);

#ifdef CHCHG_TICK_PRINTF
	reset_vdec_first_show();
    tpara.eCBType = VDEC_CB_FIRST_SHOWED;
    tpara.pCB = cb_vdec_first_show;
    vdec_io_control(v_dec, VDEC_IO_REG_CALLBACK, (UINT32)(&tpara));
#endif

#ifdef CC_USE_TSG_PLAYER
    cc_tsg_task_init();
#endif
}

INT32 chchg_play_channel(struct ft_frontend *ft, struct cc_param *param, BOOL blk_scrn)
{
    	struct libpub_cmd cmd;

		osal_task_dispatch_off();
		cc_cmd_cnt ++;
		osal_task_dispatch_on();

    	ENTER_CC_API();

    	MEMSET(&cmd, 0, sizeof(cmd));
    	cmd.cmd_type = LIBPUB_CMD_CC_PLAY;
#ifdef STAR_ADV_SUPPORT
     	if(1)
#else
     	if(hde_get_mode() == VIEW_MODE_MULTI)
#endif			
     	{
        	cmd.sync = 1;
     	}
    	else
    	{
        	cmd.sync = 0;
    	}
    	if(blk_scrn)
    	{
        	cmd.para1 = 1;
    	}
      	MEMCPY(cmd.data1, ft, sizeof(struct ft_frontend));
    	MEMCPY(cmd.data2, param, sizeof(struct cc_param));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	if(cmd.sync)
    	{
         	libpub_wait_cmd_finish(LIBPUB_FLG_CC_PLAY_BIT, OSAL_WAIT_FOREVER_TIME);
    	}
		
    	LEAVE_CC_API();
    	return SUCCESS;
}

INT32 chchg_stop_channel(struct cc_es_info *es, struct cc_device_list *dev_list, BOOL blk_scrn)
{
    	struct libpub_cmd cmd;
    
    	if(dev_list == NULL)
    	{
        	return !SUCCESS;
    	}

	ENTER_CC_API();
        
    	MEMSET(&cmd, 0, sizeof(cmd));
    	cmd.cmd_type = LIBPUB_CMD_CC_STOP;
    	cmd.para1 = blk_scrn;
    	cmd.sync = 1;
    	MEMCPY(cmd.data1, es, sizeof(struct cc_es_info));
    	MEMCPY(cmd.data2, dev_list, sizeof(struct cc_device_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_STOP_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}

INT32 chchg_pause_video(struct vdec_device *vdec)
{
    	struct libpub_cmd cmd;
    	struct cc_device_list dev_list;
    
    	if(vdec == NULL)
    	{
       	return !SUCCESS;
    	}
	ENTER_CC_API();
    
    	MEMSET(&cmd, 0, sizeof(cmd));
    	MEMSET(&dev_list, 0, sizeof(dev_list));
    	cmd.cmd_type = LIBPUB_CMD_CC_PAUSE_VIDEO;
    	cmd.sync = 1;
    	dev_list.vdec = vdec;
    	MEMCPY(cmd.data2, &dev_list, sizeof(struct cc_device_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_PAUSE_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}


INT32 chchg_resume_video(struct vdec_device *vdec)
{
    	struct libpub_cmd cmd;
    	struct cc_device_list dev_list;

    	if(vdec == NULL)
    	{
       	return !SUCCESS;
    	}
	ENTER_CC_API();
    
    	MEMSET(&cmd, 0, sizeof(cmd));
    	MEMSET(&dev_list, 0, sizeof(dev_list));
    	cmd.cmd_type = LIBPUB_CMD_CC_RESUME_VIDEO;
    	cmd.sync = 1;
    	dev_list.vdec = vdec;
    	MEMCPY(cmd.data2, &dev_list, sizeof(struct cc_device_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_PAUSE_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}

INT32 chchg_switch_audio_pid(struct cc_es_info *es, struct cc_device_list *dev_list)
{
    	struct libpub_cmd cmd;
    
    	if((es == NULL) || (dev_list == NULL))
       {
        	return !SUCCESS;
	}
    	ENTER_CC_API();
    
    	MEMSET(&cmd, 0, sizeof(cmd));
    	cmd.cmd_type = LIBPUB_CMD_CC_SWITCH_APID;
    	cmd.sync = 1;
    	MEMCPY(cmd.data1, es, sizeof(struct cc_es_info));
    	MEMCPY(cmd.data2, dev_list, sizeof(struct cc_device_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_SWITCH_APID_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}

INT32 chchg_switch_audio_chan(struct snd_device *snd, UINT8 audio_chan)
{
    	struct libpub_cmd cmd;
    	struct cc_device_list dev_list;
    	struct cc_es_info *es;
        
    	if(snd == NULL)
    	{
        	return !SUCCESS;
    	}
	ENTER_CC_API();
    
    	MEMSET(&cmd, 0, sizeof(cmd));
    	MEMSET(&dev_list, 0, sizeof(dev_list));
    	cmd.cmd_type = LIBPUB_CMD_CC_SWITCH_ACH;
    	cmd.sync = 1;
    	dev_list.snd_dev = snd;
    	es = (struct cc_es_info *)(cmd.data1);
    	es->a_ch = audio_chan;
    	MEMCPY(cmd.data2, &dev_list, sizeof(dev_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_SWITCH_ACH_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}

INT32 chchg_show_logo(struct cc_logo_info *plogo, struct cc_device_list *dev_list)
{
    	struct libpub_cmd cmd;

    	if((plogo == NULL) || (dev_list == NULL))
    	{
        	return !SUCCESS;
    	}
    	ENTER_CC_API();
    
    	MEMSET(&cmd, 0, sizeof(cmd));
    	cmd.cmd_type = LIBPUB_CMD_CC_SHOW_LOGO;
    	cmd.sync = 1;
    	MEMCPY(cmd.data1, plogo, sizeof(struct cc_logo_info));
    	MEMCPY(cmd.data2, dev_list, sizeof(struct cc_device_list));
    	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
    	libpub_wait_cmd_finish(LIBPUB_FLG_CC_LOGO_BIT, OSAL_WAIT_FOREVER_TIME);

    	LEAVE_CC_API();
    	return SUCCESS;
}

#ifdef CC_USE_TSG_PLAYER
INT32 chchg_start_patch(UINT8 slot_mask)
{
	struct libpub_cmd cmd;

	ENTER_CC_API();

	MEMSET(&cmd, 0, sizeof(cmd));
	cmd.cmd_type = LIBPUB_CMD_CC_START_PATCH;
	cmd.sync = 1;
	cmd.para1 = slot_mask;
	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);
	libpub_wait_cmd_finish(LIBPUB_FLG_CC_PATCH_BIT, OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	return SUCCESS;
}
#endif

#ifdef PUB_PORTING_PUB29
BOOL UIChChgAerialSignalMonitor(UINT32 sfreq, UINT16 bandwidth)
{
	struct libpub_cmd cmd;
	//struct cc_device_list dev_list;

	ENTER_CC_API();

	MEMSET(&cmd, 0, sizeof(cmd));	
	cmd.cmd_type = LIBPUB_CMD_CC_AERIAL_CHG_CH;
	cmd.para1 = sfreq;
	cmd.para2 = bandwidth;
	//MEMSET(&dev_list, 0, sizeof(dev_list));
	//dev_list.vdec = vdec;
	//MEMCPY(cmd.data2, &dev_list, sizeof(struct cc_device_list));
	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	return SUCCESS;
	/*struct mid27_cmd this_cmd;

	ENTER_CC_API();

	api_nim_stop_autoscan();	//50916-01Angus

	this_cmd.cmd_type = MID27_CMD_CC_AERIAL_CHG_CH;
	this_cmd.para32 = sfreq;
	this_cmd.para16 = bandwidth;

	mid27_send_cmd(&this_cmd,OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();*/

	return TRUE;
}

BOOL cc_aerial_signal_monitor(UINT32 sfreq, UINT16 bandwidth)
{
	T_NODE t_node;
	UINT32 center_freq=0;
	center_freq = sfreq + ((bandwidth*1000)>>1);

	api_nim_reset_autoscan();		//50929 yuchun

	api_nim_channel_change(
		center_freq,
		bandwidth,
		0,
		0,
		0,
		0,
		0x03/*AERIALTUNE*/,
		1,
		0);
	return TRUE;
}
#endif

//a temp solution for comping failure!
//#ifndef CI_SUPPORT
#if 0
void api_ci_start_service(struct ci_device_list *dev_list,
					struct ci_service_info *service,
					UINT8 slot_mask)
{
}
void api_ci_stop_service(struct ci_device_list *dev_list,
					struct ci_service_info *service,
					UINT8 slot_mask)
{
}
void api_ci_switch_aid(UINT32 prog_id, UINT16 pid)
{
}
#endif

#ifdef CI_PLUS_SERVICESHUNNING
void chchg_operate_ci(UINT32 msg, UINT8 slot_mask)
{
	enum ci_protect_mode prot_mode;
	P_NODE pnode;

    //libc_printf("%s\n\n",__FUNCTION__);

    //libc_printf("prog id: %X\n",ci_service.prog_id);
	if (SUCCESS != get_prog_by_id(ci_service.prog_id, &pnode))
	{
		//libc_printf("error: get prog %X failed!\n",ci_service.prog_id);
		return;
	}

	CI_SHUNNING_DEBUG("# check pnode.shunning_protected @%s\n", __FUNCTION__);
	CI_SHUNNING_DEBUG("#       pnode.shunning_protected = %d\n", pnode.shunning_protected);
	if (pnode.shunning_protected == 1) {
		// then: check current cam is shun or not
		prot_mode = ci_service_shunning(pnode.tp_id, pnode.prog_number);
	}
	else {
		// play service immediately, and start SDT monitor
		prot_mode = CI_PROTECTED_IN_ACTIVE;
	}

	if((prot_mode == CI_PROTECTED_IN_ACTIVE) || api_ci_camup_in_progress())
	{
		api_ci_start_service(&ci_dev_list, &ci_service, slot_mask);
	}
	else
	{
		api_ci_stop_service(NULL, &ci_service, slot_mask);
        // We can't bypass CAM here
#ifndef CI_PLUS_SUPPORT
		api_set_nim_ts_type(2, slot_mask);
#endif
	}
}
#endif

INT32 cc_get_cmd_cnt()
{
	return cc_cmd_cnt;
}

void UIChChgSetVideoType(UINT32 flag)
{
	pub_blk_scrn = flag? FALSE : TRUE;
}


/*************************************************************************************
*
*						Porting API For PUB29
*
*************************************************************************************/
#ifdef PUB_PORTING_PUB29


/*************************************************************************************
*			Internal Function
*************************************************************************************/
extern void get_ch_pids(P_NODE* p_node,UINT16* audioPID,UINT16* ttxPID,UINT16* subtPID,UINT32* audioidx);

BOOL prt_pre_play_channel(P_NODE *p_node, struct ft_frontend *ft, struct cc_param *param, BOOL *ci_start_service, BOOL bk_play)
{
	T_NODE t_node;
	S_NODE s_node;
	UINT8 nim_id = 0, dmx_id = 0, vdec_id = 0, ts_id = 0;
	UINT8 tmp_nim_id;

	//SYSTEM_DATA* sys_data;
	
	*ci_start_service = FALSE;

	if(SUCCESS!=get_tp_by_id(p_node->tp_id, &t_node))
		return FALSE;

	tmp_nim_id = lib_nimng_request_play(p_node->prog_id);
	if(tmp_nim_id==0)
		return FALSE;

	if(ft != NULL)
	{
		MEMSET(ft, 0, sizeof(struct ft_frontend));	
		
/*step1--- choice nim */
		nim_id = tmp_nim_id-1;
		
		get_sat_by_id(t_node.sat_id, &s_node);
		
		if(nim_id == 0)
		{
			p_node->tuner1_valid = 1;
			p_node->tuner2_valid = 0;
			s_node.tuner1_valid = p_node->tuner1_valid;
			s_node.tuner2_valid = p_node->tuner2_valid;
		}
		else 
		{
			p_node->tuner1_valid = 0;
			p_node->tuner2_valid = 1;
			s_node.tuner1_valid = p_node->tuner1_valid;
			s_node.tuner2_valid = p_node->tuner2_valid;
		}

/*
		if (sys_data->antenna_connect_type == ANTENNA_CONNECT_DUAL_SAME)
		{
			s_node.tuner2_antena.lnb_type = s_node.lnb_type;
			s_node.tuner2_antena.lnb_low = s_node.lnb_low;
			s_node.tuner2_antena.lnb_high= s_node.lnb_high;
		}
#ifdef FE_DVBS_SUPPORT		
		sat2antenna(&s_node, &ft->antenna);
#endif
*/

/*		if(t_node.ft_type == FRONTEND_TYPE_S)
		{
			ft->xpond.s_info.type = t_node.ft_type;
			ft->xpond.s_info.tp_id = t_node.tp_id;
			ft->xpond.s_info.frq = t_node.frq;
			ft->xpond.s_info.sym = t_node.sym;
			ft->xpond.s_info.pol = t_node.pol;
		}
		else if(t_node.ft_type == FRONTEND_TYPE_C)
		{
		}
		else if(t_node.ft_type == FRONTEND_TYPE_T)
*/		{
			ft->xpond.t_info.type = t_node.ft_type;
			ft->xpond.t_info.tp_id = t_node.tp_id;
			ft->xpond.t_info.frq = t_node.frq;
			ft->xpond.t_info.sym = t_node.sym;
			ft->xpond.t_info.band_width = t_node.bandwidth*1000;
			ft->xpond.t_info.fft_mode = t_node.FFT;
			ft->xpond.t_info.guard_intl = t_node.guard_interval;
			ft->xpond.t_info.modulation = t_node.modulation;
			ft->xpond.t_info.usage_type = 0x2;//channel change
			ft->xpond.t_info.fec = t_node.FEC_inner; //ft->xpond.t_info.pol
			ft->xpond.t_info.inverse = t_node.inverse;
		}	

/*step2--- choice vdec */
		vdec_id = 0; //vdec_id = is_pip_chgch ? 1 : 0;
			
/*step3--- choice dmx */
		dmx_id = nim_id;
		ft->ts_route.dmx_id = dmx_id;		
		
/*step4--- choice TS according to CI state! */
		/*if(TRUE != api_select_TS(is_pip_chgch, bk_play, api_pvr_check_dmx_canuseci(p_node->ca_mode, dmx_id) ? p_node->ca_mode : FALSE, p_node->prog_id, p_node->tp_id, dmx_id, &ts_id, ci_start_service))
		{
			return FALSE;
		}*/
		ft->ts_route.ts_route_enable = 1;
		ft->ts_route.tsiid = (nim_id==0)? TSI_SPI_0 : TSI_SPI_1;
		ft->ts_route.tsi_mode = (nim_id == 0) ? 0x83 : 0x9B;
		ts_id = (nim_id==0)? TSI_TS_A : TSI_TS_B;		
		ft->ts_route.ts_id = ts_id;
		/*if (g_ci_num == 1)
		{
			if((!api_pvr_check_dmx_canuseci(p_node->ca_mode, dmx_id)) && (ts_id == TSI_TS_A))
			{
				//libc_printf("******************************** %d\n", ci_start_service);
				SDBBP();
			}
		}*/
/* check other setting */
		*ci_start_service = (p_node->ca_mode==0) ? FALSE : TRUE;
		ft->ts_route.ci_enable = *ci_start_service;
		ft->ts_route.ci_slot_mask = 3; //(sys_data_get_ci_mode() == CI_PARALLEL_MODE) ? ((ft->ts_route.ts_id == TSI_TS_A) ? 3 : 0) : ((ft->ts_route.ts_id == TSI_TS_A) ? 1 : 2);
		ft->nim = dev_get_by_id(HLD_DEV_TYPE_NIM, nim_id);		
	}	

	if(param != NULL)
	{
		MEMSET(param, 0, sizeof(struct cc_param));

		param->es.sim_id = -1;
		param->es.blk_enable = 1;
		param->es.prog_id = p_node->prog_id;
		param->es.sat_id = p_node->sat_id;
		param->es.tp_id = p_node->tp_id;
		param->es.service_id = p_node->prog_number;
		param->es.service_type = p_node->service_type;
		//param->es.pcr_pid = (p_node->av_flag==TV_CHAN) ? p_node->pcr_pid : INVALID_PID;
		param->es.pcr_pid = p_node->pcr_pid;
		param->es.v_type = MPEG2_VIDEO_STREAM;
		param->es.v_pid = (p_node->av_flag==PROG_TV_MODE) ? p_node->video_pid : INVALID_PID;
		if(param->es.v_pid==0)
			param->es.v_pid = INVALID_PID;
		param->es.a_type = AUDIO_MPEG2;
#ifdef HDTV_SUPPORT
		if(param->es.v_pid != INVALID_PID && p_node->h264_flag)
		{
			param->es.v_pid |= H264_VIDEO_PID_FLAG;
		}
#endif
		// This for default language is not the first langusge. BUG17206 
		if (!p_node->audio_select)
		{
			UINT16	audioPID = 0,ttxPID = 0,subtPID = 0;
			UINT32	audioIdx = 0;
			get_ch_pids(p_node,&audioPID,&ttxPID,&subtPID,&audioIdx);
			if(p_node->cur_audio != audioIdx)
			{
				p_node->cur_audio= audioIdx;
				modify_prog(p_node->prog_id, p_node);
			}
		}
		param->es.a_pid = (p_node->audio_count) ? p_node->audio_pid[p_node->cur_audio] : INVALID_PID;		
		param->es.audio_no_act = FALSE;//is_pip_chgch;
		param->es.a_ch = p_node->audio_channel;
#ifdef SYS_VOLUME_FOR_PER_PROGRAM
		param->es.a_volumn = p_node->audio_volume;
#else
		param->es.a_volumn = sys_data_get_volume();//sys_data->volume;
#endif

		if(param->es.a_pid & AC3_DES_EXIST)
			param->es.a_type = AUDIO_AC3;
		else if(param->es.a_pid & AAC_DES_EXIST)
			param->es.a_type = AUDIO_MPEG_AAC;
		else if(param->es.a_pid & ADTS_AAC_DES_EXIST)
			param->es.a_type = AUDIO_MPEG_ADTS_AAC;
		
		param->es.spdif_enable = 0;
#if(AC3DEC==0)
		param->es.spdif_enable = 1;
#endif
		param->es.dmx_2play = 0;

		param->dev_list.vpo = dev_get_by_id(HLD_DEV_TYPE_DIS, 0);		
		param->dev_list.vdec = dev_get_by_id(HLD_DEV_TYPE_DECV, vdec_id);
		param->dev_list.deca = dev_get_by_id(HLD_DEV_TYPE_DECA, 0);
		param->dev_list.snd_dev = dev_get_by_id(HLD_DEV_TYPE_SND, 0);
		param->dev_list.dmx = dev_get_by_id(HLD_DEV_TYPE_DMX, dmx_id);
#ifdef HDTV_SUPPORT		
		if(p_node->h264_flag)
			param->dev_list.vdec_stop = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
		param->dev_list.vdec_hdtv = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
#endif		
	}

	return TRUE;
}

/*************************************************************************************
*			External Function
*************************************************************************************/


void set_cc_notify_callback(cc_notify_callback callback)
{
	post_play_callback = callback;
}

void get_ch_pids(P_NODE* p_node,UINT16* audioPID,UINT16* ttxPID,UINT16* subtPID,UINT32* audioidx)
{
	UINT32 i,j,k;
	UINT8 lang_in_db[MAX_AUDIO_CNT][4];
    	UINT32 audio_cnt;
    
	MEMSET(lang_in_db,0,sizeof(lang_in_db));

    audio_cnt = p_node->audio_count;
    if(audio_cnt>MAX_AUDIO_CNT)
        audio_cnt = MAX_AUDIO_CNT;

 #ifdef _DTGSI_ENABLE_   // for audio select pid not match UI
    *audioPID = p_node->audio_pid[p_node->cur_audio];
    *audioidx = p_node->cur_audio;
#else 
    if(audio_cnt == 0)
    {
        *audioPID = 0x1FFF;
        *audioidx = 0;
    }
    else if(p_node->cur_audio<audio_cnt)
    {
        *audioPID = p_node->audio_pid[p_node->cur_audio];
        *audioidx = p_node->cur_audio;
    }
    else
    {
        *audioPID = p_node->audio_pid[0];
        *audioidx = 0;
    }

    /* If this channel's audio PID has not been selected by user,then decide
      the audio PID by audio language setting */
    if( !p_node->audio_select)
    {
    	for(i=0;i<audio_cnt;i++)
    		get_audio_lang3b((UINT8 *)&p_node->audio_lang[i],lang_in_db[i]);		
    	
    	for(i=0;i<l_cc_global_lang_num;i++)
    	{
    		for(j=0;j<audio_cnt;j++)
    		{
    			if( STRCMP(l_cc_global_lang_group[i],lang_in_db[j]) == 0)
    			{
    				*audioPID = p_node->audio_pid[j];
                    *audioidx = j;
                    goto GET_AUDIO_PID_DONE;
    			}
                else
                {
                    for(k=0;k<ISO_639_LANG_MULTICODE_NUM;k++)
                    {
                        if(STRCMP(iso_639_lang_multicode[k][0],l_cc_global_lang_group[i]) == 0
                            && STRCMP(iso_639_lang_multicode[k][1],lang_in_db[j]) == 0)
                        {
                            *audioPID = p_node->audio_pid[j];
                            *audioidx = j;
                            goto GET_AUDIO_PID_DONE;
                        }
                    }
                }
    		}
    	}
    }

GET_AUDIO_PID_DONE:    
 #endif   

    *ttxPID     = p_node->teletext_pid;
    *subtPID    = p_node->subtitle_pid;
}
UINT8 get_cc_crnt_state(void)
{
#ifdef PUB_PORTING_PUB29
	return l_cc_crnt_state;
#else
	return 0;
#endif
}


UINT32 cur_channel_index;
BOOL UIChChgPlayProg(UINT8 avflag,UINT32 uChannelIndex)
{
	P_NODE p_node;
	struct ft_frontend frontend;
	struct cc_param chchg_param;
	BOOL ci_start_service = FALSE;

	if(get_prog_by_id(uChannelIndex, &p_node) != SUCCESS)
		return FALSE;

	if(TRUE != prt_pre_play_channel(&p_node, &frontend, &chchg_param, &ci_start_service, FALSE))
		return FALSE;

	cur_channel_index = uChannelIndex;


	chchg_play_channel(&frontend, &chchg_param, pub_blk_scrn);

	//case CC_CMD_RESET_CRNT_CH:
	return TRUE;
}

BOOL UIChChgStopProg(BOOL IsNeedBlkScrn)
{
	P_NODE p_node;
	struct ft_frontend frontend;
	struct cc_param chchg_param;
	BOOL ci_start_service = FALSE;
	//UINT32 tick= osal_get_tick();

	if(get_prog_by_id(cur_channel_index, &p_node) != SUCCESS)
		return FALSE;

	if(TRUE != prt_pre_play_channel(&p_node, &frontend, &chchg_param, &ci_start_service, FALSE))
		return FALSE;

#ifdef HDTV_SUPPORT
	chchg_param.es.v_pid &= 0x1fff;
#endif

	chchg_stop_channel(&(chchg_param.es), &(chchg_param.dev_list), IsNeedBlkScrn);

	cur_channel_index = -1;

	return TRUE;
}
BOOL UIChChgPauseProg(void)
{
	//P_NODE p_node;
	struct vdec_device* v_dec = (struct vdec_device*)dev_get_by_id(HLD_DEV_TYPE_DECV, 0);
	
#ifdef HDTV_SUPPORT
	//if(get_prog_by_id(cur_channel_index, &p_node) != SUCCESS)
	//	return FALSE;
	//if(p_node.h264_flag)
	if(is_cur_decoder_avc())
		v_dec = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
#endif
	chchg_pause_video(v_dec);

	return TRUE;
}

BOOL UIChChgResumeProg(void)
{
	//P_NODE p_node;
	struct vdec_device* v_dec = (struct vdec_device*)dev_get_by_id(HLD_DEV_TYPE_DECV, 0);
#ifdef HDTV_SUPPORT
	//if(get_prog_by_id(cur_channel_index, &p_node) != SUCCESS)
	//	return FALSE;
	//if(p_node.h264_flag)
	if(is_cur_decoder_avc())
		v_dec = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
#endif
	chchg_resume_video(v_dec);
 
	return TRUE;
}

BOOL UIChChgShowLogo(UINT8* pLogoData,UINT32 uDataSize,BOOL IsSync)
{	
	P_NODE p_node;
	struct cc_logo_info logo;
	struct cc_device_list dev_list;
	UINT32 tick = osal_get_tick();
	
    MEMSET(&logo, 0, sizeof(logo));
	MEMSET(&dev_list, 0, sizeof(struct cc_device_list));
    logo.addr = pLogoData;
    logo.size = uDataSize;
    logo.sto = dev_get_by_id(HLD_DEV_TYPE_STO, 0);
    dev_list.vpo = dev_get_by_id(HLD_DEV_TYPE_DIS, 0);
    dev_list.vdec = dev_get_by_id(HLD_DEV_TYPE_DECV, 0);
    dev_list.deca = dev_get_by_id(HLD_DEV_TYPE_DECA, 0);
    dev_list.snd_dev = dev_get_by_id(HLD_DEV_TYPE_SND, 0);
    dev_list.dmx = dev_get_by_id(HLD_DEV_TYPE_DMX, 0);

#ifdef HDTV_SUPPORT
	//if(get_prog_by_id(cur_channel_index, &p_node) == SUCCESS && p_node.h264_flag)
	if(is_cur_decoder_avc())
	{
		dev_list.vdec_stop = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
		dev_list.vdec_hdtv= (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
	}
#endif
	
    chchg_show_logo(&logo, &dev_list);

	libc_printf("  show_logo %d",osal_get_tick()-tick);

	return TRUE;
}

void UIChChgSetVideoType(UINT32 flag)
{
	//libpub27_config.chchg_blk_enable = flag? FALSE : TRUE;
	pub_blk_scrn = flag? FALSE : TRUE;
}

//just for building
UINT32 UIChChgSetAudLanguage(BYTE* szLangGroup,UINT32 uLangNum)
{
/*	UINT32 i,j;

	MEMSET(l_cc_global_lang_group,0,sizeof(l_cc_global_lang_group));
	if (uLangNum > CC_MAX_LANG_GROUP_SIZE)
		uLangNum = CC_MAX_LANG_GROUP_SIZE;
	for(i=0; i<uLangNum; i++)
	{
		for (j=0;j<3;j++)
		{
			l_cc_global_lang_group[i][j] = szLangGroup[i*4+j];
		}
	}

	l_cc_global_lang_num = uLangNum;
	return uLangNum;*/
	return 0;
}
BOOL UIChChgSwitchACH(UINT8 uAudioChannel)
{
	struct snd_device* snd = (struct snd_device*)dev_get_by_id(HLD_DEV_TYPE_SND, 0);
	chchg_switch_audio_chan(snd, uAudioChannel);
 
	return TRUE;
}
BOOL UIChChgSwitchAPID(UINT32 uAudioPID)
{
	struct cc_es_info es;
	struct cc_device_list dev_list;
	P_NODE p_node;
	
	MEMSET(&es,0,sizeof(es));
	MEMSET(&dev_list,0,sizeof(dev_list));
	
	if(uAudioPID & AC3_DES_EXIST)
	{
		es.a_type = AUDIO_AC3;
	}
	else
	{
		es.a_type = AUDIO_MPEG2;
	}
	es.spdif_enable = 1;
	es.a_pid = uAudioPID;
	//es.a_ch = audio_ch;
	es.a_volumn = sys_data_get_volume(); //sys_data->volume;
	dev_list.vpo = dev_get_by_id(HLD_DEV_TYPE_DIS, 0);
	dev_list.vdec = dev_get_by_id(HLD_DEV_TYPE_DECV, 0);
	dev_list.deca = dev_get_by_id(HLD_DEV_TYPE_DECA, 0);
	dev_list.snd_dev = dev_get_by_id(HLD_DEV_TYPE_SND, 0);
	dev_list.dmx = dev_get_by_id(HLD_DEV_TYPE_DMX, 0);
#ifdef HDTV_SUPPORT
	//if(get_prog_by_id(cur_channel_index, &p_node) == SUCCESS && p_node.h264_flag)
	if(is_cur_decoder_avc())
		dev_list.vdec = (struct vdec_device *)dev_get_by_name("DECV_AVC_0");
#endif
	
	chchg_switch_audio_pid(&es, &dev_list);

	return TRUE;
}

//just for building, it seem not use in 3602 -T
BOOL UIChChgApplyAudLanguage(void)
{
	#if 0
    struct mid27_cmd this_cmd;

	ENTER_CC_API();

	this_cmd.cmd_type = MID27_CMD_CC_SWITCH_AID;
	this_cmd.para32 = 0xFFFFFFFF; /* special case, for apply audio lang only */

	mid27_send_cmd(&this_cmd,OSAL_WAIT_FOREVER_TIME);

   	mid27_wait_cmd_finish(MID27_FLG_CC_SWITCH_AID_BIT,OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	#endif
	return TRUE;

}

//just for building, it seem not use in 3602 -T
void set_local_position(double longtitude,double latitude,BOOL ismutex)
{
/*	ENTER_CC_API();

	l_cc_local_longtitude = longtitude;
	l_cc_local_latitude = latitude;
	l_cc_local_ismutex = ismutex;

	LEAVE_CC_API();
	*/
}
struct monitor_param mid_para = {0, NULL};
void mid_monitor_init(struct monitor_param para)
{
	if(para.event_hand != NULL)
		mid_para.event_hand = para.event_hand;
}
#if((SYS_PROJECT_FE == PROJECT_FE_ATSC)||( SYS_PROJECT_FE == PROJECT_FE_DVBT ))
BOOL UIChChgLockProg(UINT32 cur_channel,BOOL sync)
{
	struct libpub_cmd cmd;


	ENTER_CC_API();

	MEMSET(&cmd, 0, sizeof(cmd));
	cmd.cmd_type = LIBPUB_CMD_CC_LOCK;
	cmd.sync = sync;
	cmd.para1 = cur_channel;

	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);

	if(sync)
		libpub_wait_cmd_finish(MID27_FLG_CC_LOCK_BIT, OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	return SUCCESS;
}
#endif

#if (SYS_PROJECT_FE == PROJECT_FE_DVBT) || (defined(PORTING_ATSC))
void cc_get_xpond_info(struct cc_xpond_info* xpond_info)
{
	MEMCPY(xpond_info,&(play_xpond_info), sizeof(struct cc_xpond_info));
}
BOOL UIChChgAerialSignalMonitor(UINT32 sfreq, UINT16 bandwidth)
{
	struct libpub_cmd cmd;
	//struct cc_device_list dev_list;

	ENTER_CC_API();

	MEMSET(&cmd, 0, sizeof(cmd));	
	cmd.cmd_type = LIBPUB_CMD_CC_AERIAL_CHG_CH;
	cmd.para1 = sfreq;
	cmd.para2 = bandwidth;
	//MEMSET(&dev_list, 0, sizeof(dev_list));
	//dev_list.vdec = vdec;
	//MEMCPY(cmd.data2, &dev_list, sizeof(struct cc_device_list));
	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	return SUCCESS;
	/*struct mid27_cmd this_cmd;

	ENTER_CC_API();

	api_nim_stop_autoscan();	//50916-01Angus

	this_cmd.cmd_type = MID27_CMD_CC_AERIAL_CHG_CH;
	this_cmd.para32 = sfreq;
	this_cmd.para16 = bandwidth;

	mid27_send_cmd(&this_cmd,OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();*/

	return TRUE;
}
#endif

#endif

#ifndef PUB_PORTING_PUB29

BOOL cc_aerial_signal_monitor(struct ft_frontend *ft)//(UINT32 sfreq, UINT16 bandwidth)
{
	T_NODE t_node;
	UINT32 center_freq=0;
    if(NULL == ft)
        return FALSE;
    
   //  center_freq = sfreq + ((bandwidth*1000)>>1);
    
	nim_io_control(ft->nim, NIM_DRIVER_STOP_ATUOSCAN, 0);
	//api_nim_reset_autoscan();		//50929 yuchun
#ifdef SUPPORT_FREQ_CONVERT
	as_freq_convert(&center_freq);
#endif
#ifdef EZ_ADD_SUPPORT
	psip_monitor_stop();
#endif
    frontend_tuning(ft->nim, NULL, &ft->xpond, 1);
/*
	api_nim_channel_change(
		center_freq,
		bandwidth,
		0,
		0,
		0,
		0,
		0x03, //AERIALTUNE,
		1,
		0);
*/		
#ifdef EZ_ADD_SUPPORT
	if (center_freq && menu_stack_get_top() == NULL)  // manual scan cannot enter due to will auto scan in
	{
		//soc_printf("psip_start\n");

 		if (SUCCESS == get_tp_by_id(pre_tp_id, &t_node) && center_freq == t_node.frq)
		{
		    if (get_vct_changing_flag() == TRUE)
		        set_vct_changing_flag(FALSE);
		    return TRUE;
		}		
		psip_monitor_start(center_freq, 0xffff);  // 080225 Xavier avoid tp_id check error when bigger than 57
	}
#endif

	return TRUE;
}

BOOL UIChChgAerialSignalMonitor(struct ft_frontend *ft)//(UINT32 sfreq, UINT16 bandwidth)
{
	struct libpub_cmd cmd;
	//struct cc_device_list dev_list;

	ENTER_CC_API();

	MEMSET(&cmd, 0, sizeof(cmd));	
	cmd.cmd_type = LIBPUB_CMD_CC_AERIAL_CHG_CH;
    cmd.para1 = (UINT32)ft;
	//cmd.para1 = sfreq;
	//cmd.para2 = bandwidth;
	//MEMSET(&dev_list, 0, sizeof(dev_list));
	//dev_list.vdec = vdec;
	//MEMCPY(cmd.data2, &dev_list, sizeof(struct cc_device_list));
	libpub_send_cmd(&cmd, OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();
	return SUCCESS;
	/*struct mid27_cmd this_cmd;

	ENTER_CC_API();

	api_nim_stop_autoscan();	//50916-01Angus

	this_cmd.cmd_type = MID27_CMD_CC_AERIAL_CHG_CH;
	this_cmd.para32 = sfreq;
	this_cmd.para16 = bandwidth;

	mid27_send_cmd(&this_cmd,OSAL_WAIT_FOREVER_TIME);

	LEAVE_CC_API();*/

	return TRUE;
}
#endif
